您的位置:首页 > 其它

vijosP1067Warcraft III 守望者的烦恼

2015-10-30 09:26 387 查看
vijosP1067Warcraft III 守望者的烦恼

链接:https://vijos.org/p/1067

【思路】

矩阵乘法。

可以得出递推式:

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 |

即有如下转移:



(上图转移矩阵有错)

【代码】

#include<cstdio>
#include<cstring>
#include<iostream>
#define FOR(a,b,c) for(int a=(b);a<(c);a++)
using namespace std;

const int maxn = 10+5;
const int MOD=7777777;

struct Matrix{
int r,c;
long long N[maxn][maxn];
void init(int r,int c) {
this->r=r, this->c=c;
memset(N,0,sizeof(N));
}
Matrix operator*(Matrix& B)const{
Matrix A=*this,C;
C.init(A.r,B.c);
for(int i=0;i<C.r;i++)
for(int j=0;j<C.c;j++)
for(int k=0;k<A.c;k++)
C.N[i][j] = (C.N[i][j]+A.N[i][k]*B.N[k][j])%MOD;
return C;
}
Matrix pow(int p) {
Matrix tmp=*this;
Matrix ans;
ans.init(r,r);
for(int i=0;i<r;i++) ans.N[i][i]=1;
while(p) {
if(p&1) ans=ans*tmp;
tmp=tmp*tmp;
p>>=1;
}
return ans;
}
};

int n,k;

int main() {
scanf("%d%d",&k,&n);
Matrix F,T;
T.init(k,k);
FOR(i,0,k) T.N[i][0]=1;
FOR(i,1,k) T.N[i-1][i]=1;
T=T.pow(n);
F.init(1,k);
F.N[0][0]=1;
F=F*T;
printf("%d\n",F.N[0][0]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: