CodeForces-691E Xor-sequences(矩阵快速幂)

来源:互联网 发布:乐清市知临学校招聘 编辑:程序博客网 时间:2024/05/23 16:38

E. Xor-sequences
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given n integers a1,  a2,  ...,  an.

A sequence of integers x1,  x2,  ...,  xk is called a "xor-sequence" if for every 1  ≤  i  ≤  k - 1 the number of ones in the binary representation of the number xi  xi  +  1's is a multiple of 3 and  for all 1 ≤ i ≤ k. The symbol  is used for the binary exclusive or operation.

How many "xor-sequences" of length k exist? Output the answer modulo 109 + 7.

Note if a = [1, 1] and k = 1 then the answer is 2, because you should consider the ones from a as different.

Input

The first line contains two integers n and k (1 ≤ n ≤ 1001 ≤ k ≤ 1018) — the number of given integers and the length of the "xor-sequences".

The second line contains n integers ai (0 ≤ ai ≤ 1018).

Output

Print the only integer c — the number of "xor-sequences" of length k modulo 109 + 7.

Examples
input
5 215 1 2 4 8
output
13
input
5 115 1 2 4 8
output
5

题意:给出n个数,要求从这n个数中选k个数(可以重复选取),使得这k个数的异或和后二进制中1的个数是3的倍数(注意0也算3的倍数),求出有多少种选法
题解: 矩阵快速幂,我们可以开一个n*n的邻接矩阵,如果x[u][v]>0,表示以u为起点,v为终点的长度为2的序列的异或和满足条件且有x[u][v]个,
(注意:矩阵相乘后,新矩阵的每个元素x[u][v]=x1[u][0]*x2[0][v]+x1[u][1]*x2[1][v]+...+x1[u][n-1]*x2[n-1][v],表示在u,v间插入一个数,所以长度增加1)
那么我们先将2个矩阵相乘,得到的新矩阵中,如果x[u][v]>0,表示以u为起点,v为终点的长度为3的序列的异或和满足条件且有x[u][v]个,那么我们只要把矩阵乘以k-1次所得到
的矩阵中的元素之和就是我们所求的答案

#include<cstdio>#include<algorithm>#include<string.h>#include<queue>#include<vector>using namespace std;typedef long long LL;const int maxn = 1e2 + 5;const LL mod = 1e9 + 7;struct Matrix{    LL x[maxn][maxn];    void init(){memset(x,0,sizeof(x));}}m;LL a[maxn],n,k;bool check(LL x){    int cnt=0;    while(x){        if(x&1) cnt++;        x>>=1;    }    if(cnt%3==0) return true;    return false;}Matrix MultiplyMatrix(Matrix c1,Matrix c2){    Matrix c;    c.init();    for(int i=0;i<n;i++){        for(int j=0;j<n;j++){            for(int k=0;k<n;k++){                c.x[i][j]=(c.x[i][j]+c1.x[i][k]*c2.x[k][j])%mod;            }        }    }    return c;}Matrix solve(){    Matrix ret;    k--;    ret.init();    for(int i=0;i<n;i++) ret.x[i][i]=1;    while(k){        if(k&1) ret=MultiplyMatrix(ret,m);        m=MultiplyMatrix(m,m);        k>>=1;    }    return ret;}int main(){    scanf("%I64d%I64d",&n,&k);    for(int i=0;i<n;i++) scanf("%I64d",&a[i]);    m.init();    for(int i=0;i<n;i++){        for(int j=0;j<n;j++){            if(check(a[i]^a[j])) m.x[i][j]=1;        }    }    Matrix ans=solve();    LL cnt=0;    for(int i=0;i<n;i++){        for(int j=0;j<n;j++){            cnt=(cnt+ans.x[i][j])%mod;        }    }    printf("%I64d\n",cnt);}




0 0
原创粉丝点击