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 }

 

posted @ 2016-07-06 10:42  nicetomeetu  阅读(126)  评论(0编辑  收藏  举报