Codeforces Round #307 (Div. 2) 551D - GukiZ and Binary Operations 矩阵快速幂
2016-03-12 18:25
405 查看
题意:给一个大小为n的数组,使相邻的数进行&运算得到n-1对数,把这n-1对数进行 | 运算等于k。有多少个这样的数组,答案mod m
思路:毫无思路… 因为之前不会矩阵快速幂,早就想学来着,就顺便学了。
这道题思路大概是枚举每对相邻的数的每一位是否满足当前位数都等于1
我们假设只有x对数,然后开始枚举第一位。因为只有一位所以每个0和1都代表这个数当前位数的数,ans是当前位数的方案数。枚举的是不存在相邻的方案数
x=1 就存在0和1两种情况 ans=2
x=2 00 01 10 ans=3
x=3 000 100 010 001 101 ans=5
这时候容易发现一个规律就是
x=3的时候就等于 x=2的时候后边加个0+x=1的时候加个01(因为不能和x=2情况重合,所以最后一位必须是1)
所以 f[x]=f[x-1]+f[x-2] 明显的fibonacci 然后因为n太大了,所以矩阵加速求出f
然后如果当前位数k&1<
思路:毫无思路… 因为之前不会矩阵快速幂,早就想学来着,就顺便学了。
这道题思路大概是枚举每对相邻的数的每一位是否满足当前位数都等于1
我们假设只有x对数,然后开始枚举第一位。因为只有一位所以每个0和1都代表这个数当前位数的数,ans是当前位数的方案数。枚举的是不存在相邻的方案数
x=1 就存在0和1两种情况 ans=2
x=2 00 01 10 ans=3
x=3 000 100 010 001 101 ans=5
这时候容易发现一个规律就是
x=3的时候就等于 x=2的时候后边加个0+x=1的时候加个01(因为不能和x=2情况重合,所以最后一位必须是1)
所以 f[x]=f[x-1]+f[x-2] 明显的fibonacci 然后因为n太大了,所以矩阵加速求出f
然后如果当前位数k&1<
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<queue> #include<stack> #include<string> #include<vector> #include<map> #include<set> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x&(-x)) typedef long long LL; #define maxn 10005 const int inf=(1<<31)-1; #define m MOD #define Matrix_Size 5 int Size; LL m; struct Matrix { LL mat[Matrix_Size][Matrix_Size]; void clear() { memset(mat,0,sizeof(mat)); } void output() { for(int i = 0;i < Size;i++) { for(int j = 0;j < Size;j++) printf("%d ",mat[i][j]); printf("\n"); } } Matrix operator *(const Matrix &b)const { Matrix ret; for(int i = 0;i < Size;i++) for(int j = 0;j < Size;j++) { ret.mat[i][j] = 0; for(int k = 0;k < Size;k++) { long long tmp = (long long)mat[i][k]*b.mat[k][j]%MOD; ret.mat[i][j] = (ret.mat[i][j]+tmp); if(ret.mat[i][j]>MOD) ret.mat[i][j] -= MOD; } } return ret; } }; Matrix pow_M(Matrix a,long long n) { Matrix ret; ret.clear(); for(int i = 0;i < Size;i++) ret.mat[i][i] = 1; Matrix tmp = a; while(n) { if(n&1)ret = ret*tmp; tmp = tmp*tmp; n>>=1; } return ret; } LL quick(LL n) { LL ans=1,t=2; while(n) { if(n&1) ans=(ans*t)%m; t=(t*t)%m; n>>=1; } return ans; } int main() { LL n,l,k; scanf("%lld%lld%lld%lld",&n,&k,&l,&m); if(k>=(1uLL<<l)&&l!=64) { printf("0\n"); return 0; } Matrix a,b; Size=2; a.mat[0][0]=0;a.mat[0][1]=1; a.mat[1][0]=1;a.mat[1][1]=1; b.mat[0][0]=1;b.mat[0][1]=0; b.mat[1][0]=2;b.mat[1][1]=0; a=pow_M(a,n); b=a*b; LL t1=b.mat[0][0];//不存在相邻 LL t2=(m+quick(n)-t1)%m;//存在相邻 //printf("%lld %lld\n",t1,t2); LL ans=1; for(int i=0;i<l;++i) if(k&(1uLL<<i)) ans=(ans*t2)%m; else ans=(ans*t1)%m; printf("%lld\n",ans%m); return 0; }
相关文章推荐
- Codeforces Round #197 (Div. 2)
- Codeforces Round #198 (Div. 1)
- Codeforces 405E Codeforces Round #238 (Div. 2)E
- Codeforces 407C Codeforces Round #239 (Div. 1)C
- CodeForces 449A - Jzzhu and Chocolate
- CodeForces 449 B. Jzzhu and Cities
- codeforces 618C. Constellation
- Codeforces Round #265 (Div. 2)
- Codeforces #310 div2 C. Case of Matryoshkas
- 状态压缩DP codeforces 244 Problem C. The Brand New Function 和 codeforces 165 E. Compatible Numbers
- codeforces 16 Problem E fish
- Codeforces Round332 部分题解
- CodeForces 603A_Alternative Thinking (DP)
- CodeForces 602B_Approximating a Constant Range_DP
- Codeforces round #247 for Div. 2
- Codeforces Round #246 (Div. 2)
- Codeforces #264(div 2)D.Gargari and Permutations
- Codeforces Round #236 (Div. 2)------A,B
- codeforces 257 div2 B
- Codeforces Gym100571A Cursed Query