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 }
View Code

 

转载于:https://www.cnblogs.com/ehanla/p/9811270.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值