zoukankan      html  css  js  c++  java
  • Codeforces 691E Xor-sequences

    矩阵快速幂。递推式:dp[k][i]=sum(dp[k-1][j]*f[i][j]),dp[k][i]表示的意义是序列中有k个元素,最后一个元素是i的方案数,f[i][j]=1表示i与j能放在一起,反之表示不能放在一起。因为k较大,所以可以构造矩阵进行加速。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi = acos(-1.0), eps = 1e-8;
    void File()
    {
        freopen("D:\in.txt", "r", stdin);
        freopen("D:\out.txt", "w", stdout);
    }
    inline int read()
    {
        char c = getchar();  while (!isdigit(c)) c = getchar();
        int x = 0;
        while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
        return x;
    }
    
    int n; LL k,a[105],mod=1e9+7;;
    
    struct Matrix
    {
        long long A[105][105];
        int R, C;
        Matrix operator*(Matrix b);
    };
    
    Matrix X, Y, Z;
    
    Matrix Matrix::operator*(Matrix b)
    {
        Matrix c;
        memset(c.A, 0, sizeof(c.A));
        int i, j, k;
        for (i = 1; i <= R; i++)
            for (j = 1; j <= C; j++)
                for (k = 1; k <= C; k++)
                    c.A[i][j] = (c.A[i][j] + (A[i][k] * b.A[k][j])%mod)%mod;
        c.R=R; c.C=b.C;
        return c;
    }
    
    int check(LL x)
    {
        int sz=0;
        while(x) { if(x%2==1) sz++; x=x/2; }
        if(sz%3==0) return 1; return 0;
    }
    
    void init()
    {
        memset(X.A,0,sizeof X.A);
        memset(Y.A,0,sizeof Y.A);
        memset(Z.A,0,sizeof Z.A);
    
        Z.R = 1; Z.C = n;
    
        for(int i=1;i<=n;i++) Z.A[1][i]=Y.A[i][i]=1; Y.R = n; Y.C = n;
    
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                X.A[i][j]=X.A[j][i]=check(a[i]^a[j]);
        X.R=n; X.C=n;
    }
    
    void work()
    {
        k--;
        while (k) { if (k % 2 == 1) Y = Y*X; k = k >> 1,X = X*X; } Z = Z*Y;
        LL ans=0;
        for(int i=1;i<=n;i++) ans=(ans+Z.A[1][i])%mod;
        printf("%lld
    ", ans);
    }
    
    int main()
    {
        scanf("%d%lld",&n,&k);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        init(); work();
        return 0;
    }
  • 相关阅读:
    Python 基础 (三)
    Python 基础(二)
    软件工程第四周作业
    软件工程第四周作业
    软件工程第四次作业
    软件工程第四周作业
    软件工程第三次作业
    软件工程第三周作业
    软件工程第三次作业
    Python学习之路5
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5705589.html
Copyright © 2011-2022 走看看