题目链接
1 1 1 2 2 0 0 3 7 23 47 16
234 2799 72937
题意:一个矩阵,a(0,1)=233,a(0,2)=2333,a(0,3)=23333,a(0,4)=233333.......,告诉你n,m,并且给你a(1,0),a(2,0)......a(n,0)。
a(i,j)=a(i-1,j)+a(i,j-1),1<=i,j。求a(n,m)。n<=10,m<=1000000000。
题解:由于n很小,m很大,所以容易想到构造矩阵,并用矩阵二分幂来解。我们用l1,l2....ln,表示当前列的值,初始值为a(1,0),....a(n,0)。设当前列的下一列为b1,b2,....bn。那么容易得出b1=l1+2333..,b2=l1+l2+2333..,b3=l1+l2+2333...,bn=l1+l2+..ln+2333..。而下一列的23333=当前列2333*10+3。那么我们可以这样构造矩阵,假设n==4。
l1 1 0 0 0 1 0 b1
l2 1 1 0 0 1 0 b2
l3 * 1 1 1 0 1 0 = b3
l4 1 1 1 1 1 0 b4
233.. 0 0 0 0 10 3 233..*10+3
1 0 0 0 0 0 1 1
这样我们就可以用当前列推出下一列,我们就可以用矩阵二分幂求解了。
#include<stdio.h> #include<algorithm> #include<queue> #include<stack> #include<map> #include<set> #include<vector> #include<iostream> #include<string.h> #include<string> #include<math.h> #include<stdlib.h> #define inff 0x3fffffff #define eps 1e-8 #define nn 210000 #define mod 10000007 typedef __int64 LL; using namespace std; int N,M; LL aa[20]; const int MAXN=20; const int MAXM=20; struct Matrix { int n,m; LL a[MAXN][MAXM]; void clear() { n=m=0; memset(a,0,sizeof a); } Matrix operator *(const Matrix &b) const { Matrix tmp; tmp.clear(); tmp.n=n; tmp.m=b.m; for(int k=0; k<m; k++) for(int i=0; i<n; i++) for(int j=0; j<b.m; j++) { tmp.a[i][j]+=(a[i][k]*b.a[k][j])%mod; tmp.a[i][j]%=mod; } return tmp; } }ma,ans; Matrix operator ^(Matrix x,int p) { Matrix ret; ret.clear(); ret.n=x.n; ret.m=x.m; for(int i=0; i<x.n; i++) for(int j=0; j<x.m; j++) ret.a[i][j] = (i == j ? 1 : 0); while(p) { if(p%2) ret = ret * x; x = x * x; p /= 2; } return ret; } int main() { int i,j; while(scanf("%d%d",&N,&M)!=EOF) { for(i=0;i<N;i++) { scanf("%I64d",&aa[i]); aa[i]%=mod; } ma.clear(); ma.n=ma.m=N+2; for(i=0;i<N;i++) { for(j=0;j<=i;j++) ma.a[i][j]=1; ma.a[i][N]=1; } ma.a[N][N]=10; ma.a[N][N+1]=3; ma.a[N+1][N+1]=1; ans.clear(); ans.n=N+2,ans.m=1; for(i=0;i<N;i++) ans.a[i][0]=aa[i]; ans.a[N][0]=233; ans.a[N+1][0]=1; ans=(ma^M)*ans; printf("%I64d\n",ans.a[N-1][0]); } return 0; }
#include<stdio.h> #include<algorithm> #include<queue> #include<stack> #include<map> #include<set> #include<vector> #include<iostream> #include<string.h> #include<string> #include<math.h> #include<stdlib.h> #define inff 0x3fffffff #define eps 1e-8 #define nn 210000 #define mod 10000007 typedef __int64 LL; using namespace std; int N,M; LL aa[20]; const int MAXN=20; const int MAXM=20; struct Matrix { int n,m; LL a[MAXN][MAXM]; void clear() { n=m=0; memset(a,0,sizeof a); } Matrix operator *(const Matrix &b) const { Matrix tmp; tmp.clear(); tmp.n=n; tmp.m=b.m; for(int k=0; k<m; k++) for(int i=0; i<n; i++) for(int j=0; j<b.m; j++) { tmp.a[i][j]+=(a[i][k]*b.a[k][j])%mod; tmp.a[i][j]%=mod; } return tmp; } }ma,ans; Matrix operator ^(Matrix x,int p) { Matrix ret; ret.clear(); ret.n=x.n; ret.m=x.m; for(int i=0; i<x.n; i++) for(int j=0; j<x.m; j++) ret.a[i][j] = (i == j ? 1 : 0); while(p) { if(p%2) ret = ret * x; x = x * x; p /= 2; } return ret; } int main() { int i,j; while(scanf("%d%d",&N,&M)!=EOF) { for(i=0;i<N;i++) { scanf("%I64d",&aa[i]); aa[i]%=mod; } ma.clear(); ma.n=ma.m=N+2; for(i=0;i<N;i++) { for(j=0;j<=i;j++) ma.a[i][j]=1; ma.a[i][N]=1; } ma.a[N][N]=10; ma.a[N][N+1]=3; ma.a[N+1][N+1]=1; ans.clear(); ans.n=N+2,ans.m=1; for(i=0;i<N;i++) ans.a[i][0]=aa[i]; ans.a[N][0]=233; ans.a[N+1][0]=1; ans=(ma^M)*ans; printf("%I64d\n",ans.a[N-1][0]); } return 0; }