1 1 1 2 2 0 0 3 7 23 47 16
构造矩阵就行了。具体看代码把,可以用print 把矩阵打出来看;
不知道为什么G++能过,C++数组越界,路过大神求指点。
#include<stdio.h> #include<string.h> #define Matr 15 //矩阵大小,注意能小就小 矩阵从1开始 所以Matr 要+1 #define ll __int64 struct mat//矩阵结构体,a表示内容,size大小 矩阵从1开始 但size不用加一 { ll a[Matr][Matr]; mat()//构造函数 { memset(a,0,sizeof(a)); } }; int Size; ll mod= 10000007; mat multi(mat m1,mat m2)//两个相等矩阵的乘法,对于稀疏矩阵,有0处不用运算的优化 { mat ans=mat(); for(int i=1;i<=Size;i++) for(int j=1;j<=Size;j++) if(m1.a[i][j])//稀疏矩阵优化 for(int k=1;k<=Size;k++) ans.a[i][k]=(ans.a[i][k]+m1.a[i][j]*m2.a[j][k])%mod; //i行k列第j项 return ans; } mat quickmulti(mat m,ll n)//二分快速幂 { mat ans=mat(); int i; for(i=1;i<=Size;i++)ans.a[i][i]=1; while(n) { if(n&1)ans=multi(m,ans); m=multi(m,m); n>>=1; } return ans; } void print(mat m)//输出矩阵信息,debug用 { int i,j; printf("%d\n",Size); for(i=1;i<=Size;i++) { for(j=1;j<=Size;j++) <span style="white-space:pre"> </span>printf("%I64d ",m.a[i][j]); printf("\n"); } } int main() { int i; mat gou,chu=mat();//构造矩阵 初始矩阵 int n,m; __int64 ans; while(scanf("%I64d%I64d",&n,&m)!=EOF)//n+2*n+2 { Size=n+2; chu=mat(); chu.a[1][n+1]=23; for(i=1;i<=n;i++) { scanf("%I64d",&chu.a[1][i]); chu.a[1][i]%=mod; } chu.a[1][n+2]=3; gou=mat(); for(int j=1;j<=n;j++) { if(j==1) { gou.a[n+1][j]=10; gou.a[n+2][j]=1; } gou.a[j][j]=1; for(int i=1;i<=n+2;i++) { gou.a[i][j]+=gou.a[i][j-1]; } } gou.a[n+1][n+1]=10; gou.a[n+2][n+2]=1; gou.a[n+2][n+1]=1; ans=multi(chu,quickmulti(gou,m)).a[1][n]; printf("%I64d\n",ans%mod); } return 0; }