標籤:hdu 矩陣快速冪
【題目連結】:click here~~
【題目大意】:
n個人排隊,f表示女,m表示男,包含子串‘fmf’和‘fff’的序列為O隊列,否則為E隊列,有多少個序列為E隊列。
【思路】:
用f(n)表示n個人滿足條件的結果,那麼如果最後一個人是m的話,那麼前n-1個滿足條件即可,就是f(n-1);
如果最後一個是f那麼這個還無法推出結果,那麼往前再考慮一位:那麼後三位可能是:mmf, fmf, mff, fff,其中fff和fmf不滿足題意所以我們不考慮,但是如果是
mmf的話那麼前n-3可以找滿足條件的即:f(n-3);如果是mff的話,再往前考慮一位的話只有mmff滿足條件即:f(n-4)
所以f(n)=f(n-1)+f(n-3)+f(n-4),遞推會跪,可用矩陣快速冪
構造一個矩陣:
來圖一張:
代碼:
#include<bits/stdc++.h>using namespace std;typedef long long LL;const int siz=4;int k,mod;struct mut{ int mat[4][4]; // size of matric mut() { memset(mat,0,sizeof(mat)); } void init(int v) { for(int i=0; i<=4; ++i) mat[i][i]=v; }};mut operator * (mut a,mut b){ mut c; for(int i=0; i<4; ++i) { for(int j=0; j<4; ++j) { c.mat[i][j]=0; for(int k=0; k<4; ++k) { c.mat[i][j]+=(a.mat[i][k]*b.mat[k][j])%mod; c.mat[i][j]%=mod; } } } return c;}mut operator ^(mut a,LL n){ mut c; c.init(1); while(n) { if(n&1) c=a*c; a=a*a; n>>=1; } return c;}int main(){ mut a,b,c; a.mat[0][0]=9; a.mat[1][0]=6; a.mat[2][0]=4; a.mat[3][0]=2; b.init(0); b.mat[0][0]=b.mat[0][2]=b.mat[0][3]=b.mat[1][0]=b.mat[2][1]=b.mat[3][2]=1; while(~scanf("%d%d",&k,&mod)) { if(k==0){ puts("0"); } else if(k<=4){ printf("%d\n",a.mat[4-k][0]%mod); } else{ c=b^(k-4); c=c*a; printf("%d\n",c.mat[0][0]%mod); } } return 0;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
HDU 2604 Queuing (遞推+矩陣快速冪)