HDU 2604 Queuing(矩阵快速幂)
题目链接:Queuing
题意:有一支$2^L$长度的队伍,队伍中有female和male,求$2^L$长度的队伍中除 fmf 和 fff 的队列有多少。
题解:先推导递推式:$f[i]=f[i-1]+f[i-3]+f[i-4]$
当前为f:
前一个为f(ff),那么再前一个只能为m(mff),再前一个也只能为m(mmff),即从$f[i-4]$转移过来;
前一个为m(mf),那么再前一个只能为m(mmf),即从$f[i-3]$转移过来。
当前为m:
前一个为m和f均可,即从$f[i-1]$转移过来。
推导出来啦。构造下矩阵就可以啦。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #define N 4 6 using namespace std; 7 8 typedef long long ll; 9 10 struct mat 11 { 12 ll m[N][N]= 13 { 14 {1,1,0,0}, 15 {0,0,1,0}, 16 {1,0,0,1}, 17 {1,0,0,0}, 18 }; 19 }; 20 21 mat mul(mat a,mat b,ll p) 22 { 23 mat ans; 24 int i,j,k; 25 for(i=0;i<N;i++) 26 for(j=0;j<N;j++) 27 ans.m[i][j]=0; 28 29 for(i=0;i<N;i++) 30 for(j=0;j<N;j++) 31 for(k=0;k<N;k++) 32 ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j])%p; 33 return ans; 34 } 35 36 ll matpow(ll n,ll p) 37 { 38 mat ans,tmp; 39 int i,j; 40 for(int i=0;i<N;i++) 41 for(int j=0;j<N;j++) 42 ans.m[i][j]=0; 43 44 ans.m[0][0]=9;ans.m[0][1]=6; 45 ans.m[0][2]=4;ans.m[0][3]=2; 46 n-=4; 47 while(n) 48 { 49 if(n&1) ans=mul(ans,tmp,p); 50 tmp=mul(tmp,tmp,p); 51 n=n>>1; 52 } 53 return ans.m[0][0]%p; 54 } 55 56 int main(){ 57 ll L,M; 58 while(scanf("%lld%lld",&L,&M)!=EOF){ 59 if(L==0){ 60 printf("%lld\n",1%M); 61 continue; 62 } 63 else if(L==1){ 64 printf("%lld\n",2%M); 65 continue; 66 } 67 else if(L==2){ 68 printf("%lld\n",4%M); 69 continue; 70 } 71 else if(L==3){ 72 printf("%lld\n",6%M); 73 continue; 74 } 75 printf("%lld\n",matpow(L,M)); 76 } 77 return 0; 78 }