【codeforces 691 E】【矩阵快速幂 思维题】【给定序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二进制表示中1的个数是3的倍数。问满足条件的序列个数】

本文解析了CodeForces平台上E题的解题思路及代码实现。通过预处理满足特定异或条件的数对,利用矩阵乘法和快速幂优化算法,解决了寻找长度为k的特定序列数量的问题。

传送门:http://codeforces.com/contest/691/problem/E

题意:给定序列,从序列中选择k(1≤k≤1e18)个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二进制表示中1的个数是3的倍数。问长度为k的满足条件的 序列有多少种?


思路:首先每个元素自己构成一个长度为1的满足条件的序列。
其次我们可以预处理出满足条件的vi,vj,就可以得到一个横纵为n的01矩阵。这还是很显然的。此时我们得到了以vi开头,vj结尾的长度为2的序列个数。
接下来我们发现,两个矩阵相乘,矩阵c为新得到的矩阵,此时矩阵a=b,c[i][j]=a[i][1]∗b[1][j]+a[i][2]∗b[2][j]+...+a[i][n]∗b[n][j],我们得到的即为以ai开头,aJ结尾的长度为3的序列个数!
接下来用矩阵c更新矩阵a,再与最初的01矩阵,即b相乘,得到的又为开头元素为ai,结尾元素为aj的长度为4的序列个数!
依次乘k−1次即得到结果,这部分可以用矩阵快速幂进行优化。
最后把得到的矩阵中的每个元素的值加起来即为长度为k的满足条件的序列个数!
实质上就是floyd求长度为k的道路。
巧妙的利用矩阵乘法的性质解决问题!


代码:

#include <bits/stdc++.h>
using  namespace  std;
#define ll __int64
#define mod 1000000007

const int N=105;

int n;
ll k, a[N];

struct Matrix{
    ll a[N][N];
    Matrix(){
      memset(a,0,sizeof(a));
    }
    void init(){
       for(int i=1;i<=n;++i)a[i][i]=1;
    }
    Matrix operator *(const Matrix &rhs)const{
        Matrix res;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                for(int k=1; k<=n; k++)
                    res.a[i][j]=(res.a[i][j]+a[i][k]*rhs.a[k][j]%mod)%mod;
        return res;
    }
    Matrix operator ^(ll mi)const{
        Matrix tmp=(*this),res;
        res.init();
        while(mi){
            if(mi&1)res=res*tmp;
            tmp=tmp*tmp;
            mi>>=1;
        }
        return res;
    }
};


int  main(){
    scanf("%d%lld", &n, &k);
    for(int i=1; i<=n; i++)
        scanf("%lld", &a[i]);
    Matrix A; 
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n; j++){
            if(__builtin_popcountll(a[i]^a[j])%3 == 0){
                A.a[i][j]=1;
            }
        }
    }
    A=A^(k-1);
    ll ans=0;
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n; j++){
            ans = (ans+A.a[i][j])%mod;
        }
    }
    printf("%lld\n", ans);
    return 0;
}

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 all1 ≤ 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 2
15 1 2 4 8
output
13
input
5 1
15 1 2 4 8
output
5



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值