题意:矩阵横排第0行初始是0,233,2333,23333...,通项公式为a[i][j] = a[i - 1][j] + a[i][j - 1],给出了n,m以及第0列的各值,求a[n][m]的值。
题解:因为m很大,所以无法逐项递推,再看一眼n不超过10(多半要写成向量整体算),可以猜到矩阵快速幂。以case 2为例,如图构矩阵
(活生生给做成一道线代题......)
P.S. m=0或者1的时候直接算就行(特判一下)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll MOD=10000007;
int n,m,nn;
struct Matrix {
ll v[12][12];
Matrix () {memset(v,0,sizeof(v));}
friend Matrix operator *(const Matrix &A,const Matrix &B) {
Matrix C;
for (int i=0;i<=nn;++i)
for (int j=0;j<=nn;++j)
for (int k=0;k<=nn;++k)
(C.v[i][j]+=A.v[i][k]*B.v[k][j]%MOD)%=MOD;
return C;
}
};
inline Matrix fpow(Matrix A,int k) {
Matrix R;
for (int i=0;i<=nn;++i) R.v[i][i]=1;
while (k) {
if (k&1) R=A*R;
k>>=1,A=A*A;
}
return R;
}
int main() {
// freopen("in.txt","r",stdin);
Matrix T;
while (~scanf("%d%d",&n,&m)) {
nn=n+1;
for (int i=1;i<=n;++i) {
scanf("%lld",&T.v[i][0]);
T.v[i][0]%=MOD;
}
T.v[0][1]=233;
for (int i=1;i<=n;++i)
T.v[i][1]=(T.v[i-1][1]+T.v[i][0])%MOD;
if (m<2) {
printf("%lld\n",T.v[n][m]);
continue;
}
Matrix A,B;
for (int i=0;i<=n;++i) B.v[i][0]=T.v[i][1];
B.v[nn][0]=3;
for (int i=0;i<=n;++i) A.v[i][0]=10,A.v[i][nn]=1;
A.v[nn][nn]=1;
for (int i=1;i<=n;++i)
for (int j=1;j<=i;++j)
A.v[i][j]=1;
Matrix M=fpow(A,m-1)*B;
printf("%lld\n",M.v[n][0]);
}
return 0;
}