题目:
这道题一看数据范围是10的九次方,那么普通方法肯定行不通,这时候我们用矩阵快速幂。
关于构造矩阵:http://blog.csdn.net/u011721440/article/details/39401515
代码:
#include <cstdio> #include <cstring> #include <cctype> #include <string> #include <set> #include <iostream> #include <stack> #include <cmath> #include <queue> #include <vector> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f #define mod 10000007 #define N 3 #define M 1000000+10 #define ll long long using namespace std; int n; struct Mat { ll mat[12][12]; void init() { memset(mat,0,sizeof(mat)); } void E() { init(); for(int i=0;i<n;i++) mat[i][i]=1; } void show() { printf("debug\n"); for(int i=0;i<=n+1;i++,puts("")) for(int j=0;j<=n+1;j++) printf("%lld ",mat[i][j]); printf("Over\n"); } }; Mat operator *(Mat a,Mat b) { Mat res; res.init(); for(int i=0;i<=n+1;i++) for(int j=0;j<=n+1;j++) for(int k=0;k<=n+1;k++) res.mat[i][j]+=a.mat[i][k]*b.mat[k][j],res.mat[i][j]%=mod; return res; } Mat ksm(Mat a,int b) { Mat res; res.E(); while(b>0) { if(b&1) res=a*res; a=a*a; b>>=1; } return res; } Mat getmat() { Mat res; res.init(); for(int i=0;i<n;i++) for(int j=0;j<=i;j++) res.mat[i][j]=1; for(int i=0;i<=n;i++) res.mat[n][i]=10; for(int i=0;i<=n+1;i++) res.mat[n+1][i]=1; return res; } int main() { int m; while(scanf("%d%d",&n,&m)!=EOF) { Mat ori; ori.init(); ori.mat[0][n]=23; ori.mat[0][n+1]=3; for(int i=n-1;i>=0;i--) scanf("%lld",&ori.mat[0][i]); Mat res=ori*ksm(getmat(),m); printf("%lld\n",res.mat[0][0]); } return 0; }