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;
}