vijosP1067Warcraft III 守望者的烦恼
vijosP1067Warcraft III 守望者的烦恼
【思路】
矩阵乘法。
可以得出递推式:
f[i]=sum{ f[n-1],f[n-2]…f[n-k] }
矩阵乘法加速转移如下:
1、 原始矩阵F 1 x k:
| 1,0,0,0,0,…|
2、 转移矩阵T k x k:
| 1 , 0, … |
| 1, 1 , … |
| 1, 0, 1,0 |
| 1 0, 0, 1 |
即有如下转移:
(上图转移矩阵有错)
【代码】
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #define FOR(a,b,c) for(int a=(b);a<(c);a++) 5 using namespace std; 6 7 const int maxn = 10+5; 8 const int MOD=7777777; 9 10 struct Matrix{ 11 int r,c; 12 long long N[maxn][maxn]; 13 void init(int r,int c) { 14 this->r=r, this->c=c; 15 memset(N,0,sizeof(N)); 16 } 17 Matrix operator*(Matrix& B)const{ 18 Matrix A=*this,C; 19 C.init(A.r,B.c); 20 for(int i=0;i<C.r;i++) 21 for(int j=0;j<C.c;j++) 22 for(int k=0;k<A.c;k++) 23 C.N[i][j] = (C.N[i][j]+A.N[i][k]*B.N[k][j])%MOD; 24 return C; 25 } 26 Matrix pow(int p) { 27 Matrix tmp=*this; 28 Matrix ans; 29 ans.init(r,r); 30 for(int i=0;i<r;i++) ans.N[i][i]=1; 31 while(p) { 32 if(p&1) ans=ans*tmp; 33 tmp=tmp*tmp; 34 p>>=1; 35 } 36 return ans; 37 } 38 }; 39 40 int n,k; 41 42 int main() { 43 scanf("%d%d",&k,&n); 44 Matrix F,T; 45 T.init(k,k); 46 FOR(i,0,k) T.N[i][0]=1; 47 FOR(i,1,k) T.N[i-1][i]=1; 48 T=T.pow(n); 49 F.init(1,k); 50 F.N[0][0]=1; 51 F=F*T; 52 printf("%d\n",F.N[0][0]); 53 return 0; 54 }
posted on 2015-10-30 09:26 hahalidaxin 阅读(508) 评论(0) 编辑 收藏 举报