标签:矩阵快速幂
上次西安网络赛的题了
刚开始始终构造不出递推矩阵,后来想通了。。
当我们存放递推值的矩阵是竖条的时候,我们要把该矩阵放在乘法的右端,而横条的时候放在左端。。。根据矩阵乘法的原理,这样构造递推矩阵的时候就非常简单了,把对应值放上去就行了。。。
#include<stdio.h> #include<vector> using namespace std; typedef long long ll; typedef vector<ll> vec; typedef vector<vec> mat; const int mod=10000007; int n,m; mat mul(mat a,mat b){ int A=a.size(),B=b[0].size(),C=a[0].size(); mat c(A,vec(B)); for(int i=0;i<A;i++){ for(int j=0;j<B;j++){ for(int k=0;k<C;k++){ c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mod; } } } return c; } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif while(scanf("%d%d",&n,&m)!=EOF){ mat a(n+2,vec(n+2)),b(n+2,vec(1)); for(int i=0;i<n+1;i++){ for(int j=0;j<=i;j++){ if(j==0) a[i][j]=10; else a[i][j]=1; } } for(int i=0;i<n+2;i++) a[i][n+1]=1; b[0][0]=23; b[n+1][0]=3; int tmp; for(int i=1;i<n+1;i++) scanf("%I64d",&b[i][0]); /*for(int i=0;i<n+2;i++){ for(int j=0;j<1;j++){ printf("%I64d ",b[i][j]); } printf("\n"); } printf("\n");*/ while(m){ if(m&1) b=mul(a,b); a=mul(a,a); m>>=1; } if(n==0&&m==0) printf("0\n"); else printf("%I64d\n",b[n][0]); } }
标签:矩阵快速幂
原文地址:http://blog.csdn.net/lj94093/article/details/45799181