题意:给一个n*m的矩阵,a[0][0--n]、a[0--n][0]已知,a[i][j] = a[i-1][j] + a[i][j-1]。
思路分析:暴力会超时,所以可以用矩阵乘法优化,用到了矩阵快速幂,时间复杂度为O(12*12*12*log(10^9))。注意到每一列都可以通过前一列递推得到,所以构造举证temp,使得A(i)*temp = A(i+1),现在要求第m列,A(0)*(temp^m) = A(m),注意temp增加了两列,用于构造233,,2333 = 233*10 + 3 。
代码如下:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<cstring>
#include<string>
#define LL __int64
#define MOD 10000007
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 10e-6
using namespace std;
int temp[12][12] = { {10,0,10,10,10,10,10,10,10,10,10,10},
{1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,1,1,1,1,1,1,1,1,1,1},
{0,0,0,1,1,1,1,1,1,1,1,1},
{0,0,0,0,1,1,1,1,1,1,1,1},
{0,0,0,0,0,1,1,1,1,1,1,1},
{0,0,0,0,0,0,1,1,1,1,1,1},
{0,0,0,0,0,0,0,1,1,1,1,1},
{0,0,0,0,0,0,0,0,1,1,1,1},
{0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,1}
};
LL a[20],b[20];
struct node
{
LL m[20][20];
node(){
memset(m,0,sizeof(m));
}
}A,I;
void init()
{
int i,j;
for(i = 0; i < 12; i++)
for(j = 0; j < 12; j++)
A.m[i][j] = temp[i][j];
for(i = 0; i < 12; i++)
for(j = 0; j < 12; j++)
if(i == j) I.m[i][j] = 1;
else I.m[i][j] = 0;
}
node matrixmul(node a,node b,int n)
{
int i,j,k;
node c;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
for(k = 0; k < n; k++)
c.m[i][j] = (c.m[i][j] + a.m[i][k]*b.m[k][j]%MOD)%MOD;
return c;
}
node quickpow(node a,int n,int k)
{
node b,c;
b = a;
c = I;
while(n)
{
if(n&1) c = matrixmul(b,c,k);
n>>=1;
b = matrixmul(b,b,k);
}
return c;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m) != EOF)
{
init();
a[0] = 23;a[1] = 3;
int i,j;
for(i = 2; i < n+2; i++)
scanf("%I64d",&a[i]);
node c = quickpow(A,m,n+2);
//for(i = 0; i < n+2; i++) {
//for(j = 0; j < n+2; j++)
// cout<<c.m[i][j]<<" ";
// cout<<endl;}
memset(b,0,sizeof(b));
for(i = 0; i < n+2; i++)
for(j = 0; j < n+2; j++)
b[i] = (b[i]+a[j]*c.m[j][i]%MOD)%MOD;
//for(i = 0; i < n+2; i++)
// cout<<b[i]<<" ";
//cout<<endl;
printf("%I64d\n",b[n+1]%MOD);
}
return 0;
}