Xor-sequences (codeforces 691E)
5855 단어 행렬 쾌속 멱
You are given n integers a1,a2,...,an a 1 , a 2 , . . . , a n .
A sequence of integers x1,x2,...,xk x 1 , x 2 , . . . , x k is called a “xor-sequence” if for every 1 ≤ i ≤ k - 1 the number of ones in the binary representation of the number xi x i xor x o r xi+1 x i + 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 10 9 + 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 ≤ 100, 1 ≤ k ≤ 1018 10 18 ) — the number of given integers and the length of the “xor-sequences”.
The second line contains n integers ai (0 ≤ ai ≤ 1018 10 18 ).
Output
Print the only integer c — the number of “xor-sequences” of length k modulo 109+7 10 9 + 7 .
Sample Input
5 2 15 1 2 4 8
5 1 15 1 2 4 8
Sample Output
13 5
제목 설명:
서열 a1, a2,...,an a 1 , a 2 , . . . , n, 그 중에서 k개수(중복 선택 가능)를 선택하여 서열 x1, x2,...을 구성한다.xk x 1 , x 2 , . . . , xk, xixi 이상 또는xi+1xi+1의 값을 2진법에서 1의 개수가 3의 배수(1≤i
만약에 xixi가 다르거나 xi+1xi+1의 값이 2진법에서 1의 개수가 3의 배수임을 나타낸다면 xixi와xi+1xi+1은 연결할 수 있다. 즉, ii에서 i+1i+1로 이동이 존재하고 d[i][j]=1d[i][j]=1로 이동 행렬을 얻을 수 있다.전이 행렬에 대해 k-3-1k-3 1차 행렬 곱셈을 하여 최종 행렬을 얻어 최종 행렬의 모든 값을 더하면 답이 되고 행렬의 빠른 멱으로 가속한다.해석: 최종 행렬 d[i][j]=xd[i][j]=x의 의미는aiai를 시작으로 ajaj가 끝난 만족 조건의 서열 수량은 xx개이다.
AC 코드:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int mod = 1e9+7;
struct Matrix
{
int n,m;
long long d[100][100];
Matrix (int a,int b)
{
n = a, m = b;
memset(d,0,sizeof(d));
}
void Copy(int *tmp)
{
for (int i=0;ifor (int j=0;jfor (int i=0;ifor (int j=0;j0;
for (int k=0;kif (tmp >= mod) tmp -= mod;
}
c.d[i][j] = tmp;
}
return c;
}
};
int n;
long long k,a[110];
int getnum(long long x)
{
int cnt = 0;
while (x)
{
cnt += x&1;
x>>=1;
}
return cnt % 3;
}
void solve(long long m)
{
Matrix A(100,100);
for (int i=0;i1;
Matrix B(100,100);
for (int i=0;ifor (int j=0;jif (!getnum(a[i]^a[j])) B.d[i][j] = 1;
while (m)
{
if (m & 1) A = A*B;
B = B*B;
m = m>>1;
}
long long cnt = 0;
for (int i=0;ifor (int j=0;jif (cnt >= mod) cnt -= mod;
}
printf("%lld
",cnt);
return;
}
int main()
{
while (scanf("%d %lld",&n,&k)!=EOF)
{
for (int i=0;i"%lld",&a[i]);
if (k == 1)
{
printf("%d
",n);
continue;
}
solve(k-1);
}
return 0;
}