1 条题解

  • 0
    @ 2025-8-24 22:13:18

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar NaCly_Fish
    北海虽赊,扶摇可接。

    搬运于2025-08-24 22:13:18,当前版本为作者最后更新于2019-11-24 23:58:53,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    为了方便,我们记序列 bb 下标从 11 开始,并翻转,这样可以化为标准的线性递推式。

    考虑用矩阵快速幂来解决,此处我们更改矩阵乘法的定义:将原本的乘法改为按位与,原本的加法改为按位或。

    那么就能得到:

    $$\begin{bmatrix} a_{n-1} & a_{n-2} &\dots &a_{n-k}\end{bmatrix} \times \begin{bmatrix} b_1 &+\infty &0 & \dots & 0 \\ b_{2} & 0 & +\infty & \dots & 0 \\b_3 & 0 & 0 & \dots & 0 \\ \dots & \dots & \dots & \dots & \dots \\ b_{k-1} & 0 & 0 & \dots & +\infty\\ b_k & 0 & 0 & \dots & 0\end{bmatrix} $$$$=\begin{bmatrix} a_n & a_{n-1} &\dots &a_{n-k+1}\end{bmatrix} $$

    这里的 ++\infty 指的是二进制中每一位都是 11 的数。

    然后直接做就行了。

    (水题解的屑)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<bitset>
    #define N 100003
    #define reg register
    #define ull unsigned long long
    #define inf 0xffffffffffffffffull
    using namespace std;
    
    inline void read(int &x){
        x = 0;
        char c = getchar();
        while(c<'0'||c>'9') c = getchar();
        while(c>='0'&&c<='9'){
            x = (x<<3)+(x<<1)+(c^48);
            c = getchar();
        }
    }
    
    struct matrix{
        ull a[101][101];
        int siz;
    
        inline matrix(int siz=0):siz(siz){ memset(a,0,sizeof(a)); }
        inline matrix operator * (const matrix& b) const{
            matrix res = matrix(siz);
            for(reg int i=0;i!=siz;++i)
            for(reg int j=0;j!=siz;++j)
            for(reg int k=0;k!=siz;++k)
                res.a[i][j] |= a[i][k]&b.a[k][j];
            return res;    
        }
    };
    
    inline matrix power(matrix a,int t){
        matrix res = matrix(a.siz);
        for(reg int i=0;i!=a.siz;++i) res.a[i][i] = inf;
        while(t){
            if(t&1) res = res*a;
            a = a*a;
            t >>= 1;
        }
        return res;
    }
    
    int n,k;
    ull a[N],f[103];
    matrix A;
    
    int main(){
        ull ans = 0;
        scanf("%d%d",&n,&k);
        for(reg int i=0;i<k;++i) scanf("%llu",&a[i]);
        for(reg int i=1;i<=k;++i) scanf("%llu",&f[i]);
        if(n<=k){
            printf("%llu",a[n]);
            return 0;
        }
        reverse(f+1,f+k+1);
        for(reg int i=0;i!=k;++i) A.a[i][0] = f[i+1];
        for(reg int i=1;i!=k;++i) A.a[i-1][i] = inf;
        A.siz = k;
        A = power(A,n-k+1);
        for(reg int i=0;i<k;++i)
            ans |= a[k-i-1]&A.a[i][0];
        printf("%llu",ans);
        return 0;
    }
    
    • 1

    信息

    ID
    4691
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者