hdu 5015(矩阵快速幂z )
a[i][j] = a[i-1][j] + a[i][j-1]
m.特别大,可以计算出第一列,找出规律,构建一个特殊的矩阵,运用快速幂
设矩阵x:
1 0 0 0 ... |10 1
1 1 0 0 ... |10 1
1 1 1 0 ... |10 1
1 1 1 1 ... |10 1
...... ... | ...
0 0 0 0 ... |10 1
0 0 0 0 ... | 0 1
用最后两行来实现 233.....,求出x*第一列 = 第二列 。
所以最终答案 = x ^ m * 第一列 (矩阵的运用很灵活)
#include <cstdio> #include <cstring> #define mod 10000007 typedef long long ll; int n; struct mat { ll q[16][16]; mat() { memset(q,0,sizeof(q)); } }; mat mat_mul(mat a,mat b) { mat re; for(int i=0; i<=n; i++) { for(int j=0; j<=n; j++) { for(int k=0; k<=n; k++) { re.q[i][j]+=a.q[i][k]*b.q[k][j]; re.q[i][j]%=mod; } } } return re; } mat mat_pow(mat m,int num) { mat re; mat tmp=m; for(int i=0; i<=n; i++) { re.q[i][i]=1; } while(num) { if(num&1) { re=mat_mul(re,tmp); } tmp=mat_mul(tmp,tmp); num>>=1; } return re; } int main() { int m; while(scanf("%d%d",&n,&m) != EOF) { mat p,orz; for(int i = 0; i < n; i++) scanf("%I64d",&p.q[i][0]); p.q[n][0] = 23; n++; p.q[n][0] = 3; for(int i=0; i<n-1; i++) { for(int j=0; j<=i; j++) { orz.q[i][j]=1; } orz.q[i][n-1]=10; orz.q[i][n]=1; } orz.q[n][n] = orz.q[n-1][n] = 1; orz.q[n-1][n-1] = 10; mat tmp = mat_pow(orz,m); mat ans= mat_mul(tmp,p); printf("%I64d\n",ans.q[n-2][0]); } return 0; }