233 Matrix HDU - 5015
考察:矩阵快速幂
思路:
题目的递推式是找不到关系矩阵的,由此必须换一个思路.由题目的数据范围发现n小m大,可以考虑由第i列推到第i+1列,我们要由一个1x(n+2)的矩阵*(n+2)x(n+2)的矩阵 = 新的1xn+2的矩阵.从常数项先考虑,我们要从233->2333. 显然 2333 = 233*10+3.考虑构造10和 3,再将题目给定的数据放入剩下的行中,可以由题目给定的公式推出下一列.
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 typedef long long LL; 6 const int Mod = 10000007,N = 15; 7 int n,m,f[N],a[N][N]; 8 void inits() 9 { 10 f[0] = 23; f[n+1] = 3; 11 for(int i=1;i<=n;i++) scanf("%d",&f[i]); 12 for(int i=1;i<=n;i++) 13 for(int j=1;j<=n;j++) 14 if(i<=j) a[i][j] = 1; 15 else a[i][j] = 0; 16 for(int i=0;i<n+2;i++) a[0][i] = 10,a[n+1][i] = 1; 17 a[0][n+1] = 0; 18 } 19 void mul(int f[],int a[][N]) 20 { 21 int res[N]; 22 memset(res,0,sizeof res); 23 for(int i=0;i<n+2;i++) 24 for(int j=0;j<n+2;j++) 25 res[i] = (res[i]+(LL)f[j]*a[j][i])%Mod; 26 memcpy(f,res,sizeof res); 27 } 28 void mulself(int a[][N]) 29 { 30 int res[N][N]; 31 memset(res,0,sizeof res); 32 for(int i=0;i<n+2;i++) 33 for(int j=0;j<n+2;j++) 34 for(int k=0;k<n+2;k++) 35 res[i][j] = (res[i][j]+(LL)a[i][k]*a[k][j])%Mod; 36 memcpy(a,res,sizeof res); 37 } 38 int main() 39 { 40 while(scanf("%d%d",&n,&m)!=EOF) 41 { 42 memset(f,0,sizeof f); 43 memset(a,0,sizeof a); 44 inits(); 45 while(m) 46 { 47 if(m&1) mul(f,a); 48 mulself(a); 49 m>>=1; 50 } 51 printf("%d\n",f[n]); 52 } 53 return 0; 54 }