HDU 2604 - Queuing
长度为 n 有男有女的队伍里没有 fmf 和 fff 的序列有多少
判断最后一个人无法得出结论
于是判断最后两人的递推式:
fm(n) = mm(n-1) //最后两人为fm的长度为n的队伍 只能由 mm(n-1)得到
mf(n) = fm(n-1)+ ff(n-1)
ff(n) = fm(n-1)
mm(n) = mf(n-1)+ mm(n-1)
最后S(n)=fm(n)+mf(n)+ff(n)+mm(n);
|1 1 1 1 1| | S(n-1) | | S(n) |
|0 0 0 0 1| | fm(n-1)| | fm(n)|
|0 1 0 1 0| * | mf(n-1)| = | mf(n)|
|0 1 0 0 0| | ff(n-1)| | ff(n)|
|0 0 1 0 1| | mm(n-1)| | mm(n)|
剩下的就是矩阵快速幂了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 #define LL long long 6 struct P{ 7 int a[6][6]; 8 }; 9 int b[5]={0,1,1,1,1}; 10 int ans,n,mod; 11 P s,c; 12 P mult(P a,P b) 13 { 14 P c; 15 memset(c.a,0,sizeof(c.a)); 16 for(int i=1;i<=4;i++) 17 { 18 for(int j=1;j<=4;j++) 19 { 20 for(int k=1;k<=4;k++) 21 c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j] )%mod; 22 } 23 } 24 return c; 25 } 26 void ini() 27 { 28 memset(s.a,0,sizeof(s.a)); 29 memset(c.a,0,sizeof(c.a)); 30 s.a[1][3]=1; 31 s.a[2][2]=1; s.a[2][4]=1; 32 s.a[3][2]=1; 33 s.a[4][1]=1; s.a[4][3]=1; 34 } 35 void fuc(int n) 36 { 37 for(int i=1;i<=5;i++) c.a[i][i]=1; 38 while(n) 39 { 40 if(n&1) 41 { 42 c=mult(c,s); 43 } 44 s=mult(s,s); 45 n>>=1; 46 } 47 } 48 int main() 49 { 50 while(~scanf("%d%d",&n,&mod)) 51 { 52 if(n==1) 53 { 54 puts("2"); 55 continue; 56 } 57 ini(); 58 fuc(n-2); 59 ans=0; 60 for(int i=1;i<=4;i++) 61 { 62 for(int j=1;j<=4;j++) 63 { 64 ans=(ans+c.a[i][j]*b[j])%mod; 65 } 66 } 67 printf("%d\n",ans); 68 } 69 }
我自倾杯,君且随意