Codeforces 691 E Xor-sequences 矩阵快速幂

来源:互联网 发布:c语言考题 编辑:程序博客网 时间:2024/05/29 08:15

题意

从n个数中挑选k个数做排列(是排列哦,如果两个数相同不判重),如果这k个数中,相邻的两个数异或的二进制结果中有3的倍数个1,这样的排列就是满足条件的。最后输出满足条件的排列的个数。

题解

处理出一个矩阵G,g[i][j] 表示num[i] 和 num[j] 异或满足条件
可知 G2 = G*G 中的 G2[i][j]就是以num[i]开头, num[j] 结尾,且k=3的满足条件的个数
G的n次方就是,Gn[i][j]就是以num[i]开头, num[j] 结尾,且k=n+1的满足条件的个数
用 矩阵快速幂 求出G(k-1)的所有元素和即为所求

代码

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#define mod 1000000007using namespace std;typedef long long ll;const ll MAX_N = 110LL;ll n,k;ll num[MAX_N];struct graph{    ll a[MAX_N][MAX_N];    friend graph operator * (graph &A, graph &B)    {        graph C;        for(ll i=0;i<n;i++)        {            for(ll j=0;j<n;j++)            {                C.a[i][j] = (ll)0;                for(ll k=0;k<n;k++)                {                    C.a[i][j] = (C.a[i][j] + (A.a[i][k]*B.a[k][j])%mod) % mod;                }            }        }        return C;    }    void init()    {        for(ll i=0;i<n;i++)        {            a[i][i] = 1;            for(ll j=i+1;j<n;j++)            {                a[i][j] = a[j][i] = 0;            }        }    }    friend ostream& operator << (ostream &io, const graph &A)    {        for(ll i=0;i<n;i++)        {            for(ll j=0;j<n;j++)            {                io<<A.a[i][j]<<" ";            }            io<<endl;        }        return io;    }};graph mod_pow(graph tg, ll kk){    graph g;    g.init();    while(kk)    {        if(kk%2)        {            g = g*tg;        }        kk = kk>>1;        tg = tg*tg;    }    return g;}int main(){    while(scanf("%I64d%I64d",&n,&k)!=EOF)    {        for(ll i=0;i<n;i++)        {            scanf("%I64d",&num[i]);        }        graph g2;        for(ll i=0;i<n;i++)        {            g2.a[i][i] = 1LL;            for(ll j=i+1;j<n;j++)            {                ll x = num[i]^num[j];                ll cnt = 0LL;                while(x)                {                    cnt += x&1;                    x = x>>1;                }                if(cnt%3==0)                {                    g2.a[i][j] = g2.a[j][i] = 1;                }                else                    g2.a[i][j] = g2.a[j][i] = 0;            }        }        graph gk = mod_pow(g2, k-1);        ll ans=0;        for(ll i=0;i<n;i++)        {            for(ll j=0;j<n;j++)            {                ans = (ans+ gk.a[i][j])%mod;            }        }        cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击