UVa - 10870 - Recurrences ( 矩阵快速幂 )

来源:互联网 发布:域名地址解析 编辑:程序博客网 时间:2024/06/03 12:20

题目大意:

f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + . . . + adf(n − d), for n > d,

最关键的就是题目中的这句话,当n>d的时候,递推关系如上

如果n <= d 直接输出结果即可( 题目中会给出结果 )


思路:写出递推矩阵:根据递推矩阵写方程即可。




#include<cstdio>#include<cstring>#define LL long longusing namespace std;LL d,n,k,m;LL a[16],f[16];struct Matrix{LL m[16][16];Matrix(){memset(m,0,sizeof(m));}};Matrix Mul(Matrix x ,Matrix y){Matrix ans;for(int i=0 ;i<d ;i++){for(int j=0 ;j<d ;j++){for(int k=0 ;k<d ;k++){ans.m[i][j] = ( ans.m[i][j] +  x.m[i][k] * y.m[k][j] )%m;}}}return ans;}Matrix q_pow(Matrix x,int k){Matrix ans;for(int i=0 ;i<d ;i++){ans.m[i][i]=1;}while(k){if(k&1) ans = Mul(ans,x);x = Mul(x,x);k >>= 1;}return ans;}int main(){LL a0,a1,a2,a3,a4,a5,a6,a7,a8,a9;while(~scanf("%lld%lld%lld", &d, &n, &m) && d){for(int i=1 ;i<=d ;i++) scanf("%lld",&a[i]);for(int i=1 ;i<=d ;i++) scanf("%lld",&f[i]);if(n<=d){printf("%lld\n",f[n]);}else{Matrix T;for(int i=0 ;i<d ;i++) T.m[0][i] = a[i+1];for(int i=1 ;i<d ;i++) T.m[i][i-1] = 1;Matrix ans = q_pow(T,n-d);LL res = 0;for(int i=0 ;i<d ;i++){res = (res + ans.m[0][i]*f[d-i])%m;}printf("%lld\n",(res+m)%m);}}return 0;} 



1 0
原创粉丝点击