题面

传送门:http://codeforces.com/problemset/problem/691/E
E. Xor-sequences
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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 ≤ 100, 1 ≤ 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
inputCopy
5 2
15 1 2 4 8
outputCopy
13
inputCopy
5 1
15 1 2 4 8
outputCopy
5
题目大意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二进制中1的个数是3的倍数。问长度为k的满足条件的序列有多少种?

分析:

1.DP方程的推导

设dp[i][j]dp[i][j]表示前i位以j结尾的方案数

dp[i][j]=∑ix=1dp[i−1][x]dp[i][j]=∑x=1idp[i−1][x]
(bitcount(a[x](bitcount(a[x] xorxor a[i])moda[i])mod 3≡1)3≡1)
bitcount(x)表示x的二进制中1的个数

2.矩阵快速幂的优化

我们发现,状态转移方程的形式类似矩阵乘法
因为可以这样变形:dp[i][j]=∑ix=1dp[i−1][x]×(bitcount(a[x]dp[i][j]=∑x=1idp[i−1][x]×(bitcount(a[x] xorxor a[i])moda[i])mod 3==1)3==1)

所以状态转移方程可以写成这样
⎡⎣⎢⎢⎢⎢⎢dp[i][1]dp[i][2]⋮dp[i][n]⎤⎦⎥⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢⎢⎢⎢101…01…⋱11⎤⎦⎥⎥⎥⎥⎥⎥⎥×⎡⎣⎢⎢⎢⎢⎢dp[i−1][1]dp[i−1][2]⋮dp[i−1][n]⎤⎦⎥⎥⎥⎥⎥[dp[i][1]dp[i][2]⋮dp[i][n]]=[100…111⋱…1]×[dp[i−1][1]dp[i−1][2]⋮dp[i−1][n]]

右边那个很多1和0 的矩阵是n×nn×n的状态转移矩阵,第i行第j列为1代表bitcount(a[x]bitcount(a[x] xorxor a[i])moda[i])mod 3≡13≡1,否则为0
显然对角线全部为1(一个数异或它本身为0)
在DP之前我们可以预处理这个矩阵

由于最终答案为∑nj=1dp[k][j]∑j=1ndp[k][j],
状态转移方程可以改写为
⎡⎣⎢⎢⎢⎢⎢dp[k][1]dp[k][2]⋮dp[k][n]⎤⎦⎥⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢⎢⎢⎢101…01…⋱11⎤⎦⎥⎥⎥⎥⎥⎥⎥k−1×⎡⎣⎢⎢⎢⎢⎢dp[1][1]dp[1][2]⋮dp[1][n]⎤⎦⎥⎥⎥⎥⎥[dp[k][1]dp[k][2]⋮dp[k][n]]=[100…111⋱…1]k−1×[dp[1][1]dp[1][2]⋮dp[1][n]]

首先很显然每个数构成一个满足条件的序列,所以dp[1][j]=1
所以没有必要存储dp数组,直接计算出矩阵k-1次方,再将矩阵内所有的值加起来即可

时间复杂度分析:
预处理时间复杂度O(n2)O(n2)
矩阵乘法时间复杂度O(n3)O(n3)
快速幂时间复杂度O(log2k)O(log2k)
总时间复杂度O(n3log2k)O(n3log2k)

代码:

//CF 691E
#include<iostream>
#include<cstdio>
#include<cstring>
#define SIZE 105
#define maxn 105
using namespace std;
const long long mod=1000000007;
int n;
long long k;
long long num[maxn];
struct matrix {//矩阵
int n;//长
int m;//宽
long long a[SIZE][SIZE];
matrix() {//构造函数
n=2;
m=2;
memset(a,0,sizeof(a));
}
matrix(int x,int y) {
n=x;
m=y;
memset(a,0,sizeof(a));
}
void print() {
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
printf("%d ",a[i][j]);
}
printf("\n");
}
}
void setv(int x) {//初始化
if(x==0) {
memset(a,0,sizeof(a));
}
if(x==1) {
memset(a,0,sizeof(a));
for(int i=1; i<=n; i++) a[i][i]=1;
}
}
friend matrix operator *(matrix x,matrix y) {//矩阵乘法
matrix tmp=matrix(x.n,y.m);
for(int i=1; i<=x.n; i++) {
for(int j=1; j<=y.m; j++) {
tmp.a[i][j]=0;
for(int k=1; k<=y.n; k++) {
tmp.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod;
}
tmp.a[i][j]%=mod;
}
}
return tmp;
}
};
matrix fast_pow(matrix x,long long k) {//矩阵快速幂
matrix ans=matrix(n,n);
ans.setv(1);//初始化为1
while(k>0) {//类似整数快速幂
if(k&1) {
ans=ans*x;
}
k>>=1;
x=x*x;
}
return ans;
}
long long count_1(long long x) {//算1的个数
long long ans=0;
while(x>0){
if(x&1) ans++;
x/=2;
}
return ans;
}
int main() {
scanf("%d %I64d",&n,&k);
for(int i=1; i<=n; i++) scanf("%I64d",&num[i]);
matrix xor_mat=matrix(n,n);
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
if(count_1(num[i]^num[j])%3==0 )xor_mat.a[i][j]=1;
else xor_mat.a[i][j]=0;
}
}
xor_mat=fast_pow(xor_mat,k-1);
long long ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ans=ans+xor_mat.a[i][j];
}
ans%=mod;
}
printf("%I64d\n",ans);
}

Codeforces 691E题解 DP+矩阵快速幂的更多相关文章

  1. Codeforces 691E Xor-sequences(矩阵快速幂)

    You are given n integers a1,  a2,  ...,  an. A sequence of integers x1,  x2,  ...,  xk is called a & ...

  2. CodeForces - 691E Xor-sequences 【矩阵快速幂】

    题目链接 http://codeforces.com/problemset/problem/691/E 题意 给出一个长度为n的序列,从其中选择k个数 组成长度为k的序列,因为(k 有可能 > ...

  3. codeforces E. Okabe and El Psy Kongroo(dp+矩阵快速幂)

    题目链接:http://codeforces.com/contest/821/problem/E 题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y- ...

  4. Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】

    题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...

  5. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  6. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  7. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  8. bnuoj 34985 Elegant String DP+矩阵快速幂

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant s ...

  9. BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*

    BZOJ5298 CQOI2018 交错序列 [DP+矩阵快速幂优化] Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻 ...

随机推荐

  1. 转 Nacos集群环境搭建

    转载 送上nacos-server-1.1.3 链接:https://pan.baidu.com/s/11r3OeffHN8AwKLurmmzJmg  密码:wdu2 下载↓↓↓↓ https://g ...

  2. 在Wi-Fi路由器中发现了新的安全漏洞

    黑客利用两种互联网通用协议的互动的漏洞:传输控制协议,或TCP和Wi-Fi.该漏洞利用并不针对任何传统的安全漏洞.相反,安全方面的弱点在于20多年前制定的基本Wi-Fi设计决策极难改变. 中国黑客教父 ...

  3. NOIP2016 D2T2 蚯蚓

    洛谷P2827 其实是一道不是很难的模拟题,暴力好像可以拿80,AC的话要发现其中隐含的单调性 首先是一个小技巧,每次将所有蚯蚓的长度都+q肯定时间复杂度很大,那我们就想,其他所有的蚯蚓加,就相当于取 ...

  4. jq 获取各个元素的宽度高度的方法

    JS获取各种宽度.高度的简单介绍: scrollHeight: 获取对象的滚动高度. scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离 scrollTop:设置或获 ...

  5. ipcloud上传裁切图片,保存为base64再压缩传给后台

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...

  6. warp(图像仿射变换)

    仿射变换是一种二维坐标(x,y)到二维坐标(u,v)的线性变换. 对应的齐次坐标矩阵表示形式为: 仿射变换特点: 直线经仿射变换后依然为直线: ’直线之间的相对位置关系保持不变,平行线经仿射变换后依然 ...

  7. ionic slide组件使用

    ionic学习使用笔记 slide 组件的使用   开始做的时候,遇到了个要用ionic实现 有一系列的序列需要展示,但是当前页面上只能展示一小部分,剩余的在没有出现时是隐藏的,还得能滑动出现,但是又 ...

  8. 修改docker默认网段

    一. 修改普通docker run启动的容器的网段 https://blog.51cto.com/13670314/2345518?source=dra https://blog.csdn.net/w ...

  9. 启用和配置 FILESTREAM

    2017/08/23 在开始使用 FILESTREAM 之前,必须在 SQL Server 数据库引擎实例中启用 FILESTREAM. 本主题说明了如何使用 SQL Server 配置管理器来启用 ...

  10. Php.ini 中文注释详细

    Php.ini 中文注释 这个文件控制了PHP许多方面的观点.为了让PHP读取这个文件,它必须被命名为   ; ´php.ini´.PHP 将在这些地方依次查找该文件:当前工作目录:环境变量PHPRC ...