Blocks [POJ3734] [矩阵快速幂]
Posted ibilllee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Blocks [POJ3734] [矩阵快速幂]相关的知识,希望对你有一定的参考价值。
题意:
有长度为n的一排格子,每个格子里面可以任意填入1,2,3,4四个数字,问1,2都为偶数个的方案
T组数据,每组数据一个n(<=1e9)
样例输入
2
1
2
样例输出
2
6
分析
设dp[i][0/1/2/3]分别为处理到第i个,1和2的个数分别为 全偶、1偶2奇、1奇2偶,全奇
那么dp转移方程为
dp[i][0]=2dp[i-1][0]+dp[i-1][1]+dp[i-1][2] 填的分别是 3/4 1 2
dp[i][1]=dp[i-1][0]+2dp[i-1][1]+dp[i-1][3] 填的分别是 2 3/4 1
dp[i][2]=dp[i-1][0]+2dp[i-1][2]+dp[i-1][3] 填的分别是 1 3/4 2
dp[i][3]=dp[i-1][1]+dp[i-1][2]+2dp[i-1][3] 填的分别是 1 2 3/4
我们发现dp[i][1]和dp[i][2]可以合并在一起
那么将dp[i][1]和dp[i][2]合并为dp[i][1],dp[i][3]改为dp[i][2]
那么dp转移方程简化为:(简化方式为上面2式和3式相加,dp[i][1]和dp[i][2]替换为dp[i][1],dp[i][3]替换为dp[i][2])
dp[i][0]=2dp[i-1][0]+dp[i-1][1]
dp[i][1]=2dp[i-1][0]+2dp[i-1][1]+2dp[i-1][3]
dp[i][2]=dp[i-1][1]+2dp[i-1][2]
我们发现n=1e9直接推会T,所以就上矩阵快速幂,初始矩阵为
| 2 2 0 |
| 0 0 0 |
| 0 0 0 |
转置矩阵为
| 2 2 0 |
| 1 2 1 |
| 0 2 2 |
代码
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<stack> 5 #include<cmath> 6 #include<cstdio> 7 #include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 #define RG register int 11 #define rep(i,a,b) for(RG i=a;i<=b;++i) 12 #define per(i,a,b) for(RG i=a;i>=b;--i) 13 #define ll long long 14 #define inf (1<<29) 15 using namespace std; 16 ll T,n; 17 const ll mo=10007; 18 inline int read() 19 { 20 int x=0,f=1;char c=getchar(); 21 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 22 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} 23 return x*f; 24 } 25 26 struct Mat{ 27 ll a[3][3]; 28 Mat(){memset(a,0,sizeof(a));} 29 inline ll * operator [] (const int x){return a[x];} 30 inline Mat operator *(Mat b) 31 { 32 Mat ans; 33 rep(i,0,2) rep(j,0,2) rep(k,0,2) 34 (ans[i][j]+=(a[i][k]*b[k][j]))%=mo; 35 return ans; 36 } 37 }; 38 39 void work() 40 { 41 Mat S,T; 42 S[0][0]=2,S[0][1]=2,S[0][2]=0, 43 T[0][0]=2,T[0][1]=2, 44 T[1][0]=1,T[1][1]=2,T[1][2]=1, 45 T[2][1]=2,T[2][2]=2; 46 while(n) 47 { 48 if(n&1)S=S*T; 49 T=T*T; 50 n>>=1; 51 } 52 printf("%lld ",S[0][0]); 53 } 54 55 int main() 56 { 57 T=read(); 58 while(T--) 59 { 60 n=read(); 61 work(); 62 } 63 return 0; 64 }
以上是关于Blocks [POJ3734] [矩阵快速幂]的主要内容,如果未能解决你的问题,请参考以下文章