题目链接:
HDU 5015 233 Matrix
/*
* 题意:
* 定义a[0][1]=233,a[0][2]=2333,a[0][3]=23333,...给出n个数依次为a[1][0],a[2][0],
* a[3][0]...a[n][0],且a[i][j]=a[i][j-1]+a[i-1][j](i>=1,j>=1),求出a[n][m].
* 其中n<=10,m<=10^9.
* 分析:
* 由a[i][j]=a[i][j-1]+a[i-1][j](i>=1,j>=1),往前递推可得:
* a[i][j]=a[0][j-1]+a[1][j-1]+..+a[i][j-1]+a[0][j].
* 并且a[0][i]=a[0][i-1]*10+3,结合可构造一个(n+2)阶方阵
* A=
* 1 0 0 0 . . . 0 0
* 1 10 0 0 . . . 0 0
* 0 1 1 0 . . . 0 0
* . . . . . . . . .
* 0 1 1 1 . . . 1 0
* 0 1 1 1 . . . 1 1.
* 使得:
* 3 3
* a[i][1] a[i+1][1]
* a[1][i] a[1][i+1]
* A * a[2][i] = a[2][i+1]
* . . . . . .
* a[n][i] a[n][i+1]
*然后运用矩阵快速幂即可.
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const long long mod=(long long)(1e7+7);
struct Matrix{
int row,col;
long long data[15][15];
}ans,cur;
void Init(Matrix& x,int n)
{
x.row=x.col=n+2;
for(int i=1;i<=n+2;i++){
for(int j=1;j<=n+2;j++){
if(i==1){
if(j==1) x.data[i][j]=1;
else x.data[i][j]=0;
}else if(i==2){
if(j==1) x.data[i][j]=1;
else if(j==2) x.data[i][j]=10;
else x.data[i][j]=0;
}else{
if(j==1||j>i) x.data[i][j]=0;
else x.data[i][j]=1;
}
//if(j==n+2) x.data[i][j]=1;
}
}
}
Matrix multiply(Matrix a,Matrix b)
{
Matrix anss;
anss.row=a.row;
anss.col=b.col;
memset(anss.data,0,sizeof(anss.data));
for(int i=1;i<=anss.row;i++){
for(int j=1;j<=anss.col;j++){
for(int k=1;k<=a.col;k++){
anss.data[i][j]+=a.data[i][k]*b.data[k][j];
anss.data[i][j]%=mod;
}
}
}
return anss;
}
Matrix quick_power(Matrix a,long long m)
{
Matrix anss,tmp=a;
anss.row=a.row;
anss.col=a.col;
memset(anss.data,0,sizeof(anss.data));
for(int i=1;i<=anss.row;i++)
anss.data[i][i]=1;
while(m)
{
if(m&1) anss=multiply(anss,tmp);
tmp=multiply(tmp,tmp);
m>>=1;
}
return anss;
}
void debug(Matrix x,int i)
{
printf("debug case %d: row=%d col=%d\n",i,x.row,x.col);
for(int i=1;i<=x.row;i++){
for(int j=1;j<=x.col;j++){
printf("%I64d ",x.data[i][j]);
}
printf("\n");
}
}
int main()
{
//freopen("Bin.txt","r",stdin);
int n;
long long m;
while(~scanf("%d %I64d",&n,&m)){
Init(ans,n);
cur.row=n+2;
cur.col=1;
cur.data[1][1]=3;
cur.data[2][1]=233;
for(int i=1;i<=n;i++)
scanf("%I64d",&cur.data[i+2][1]);
//printf("*****************\n");
//debug(ans,1);
//debug(cur,2);
ans=quick_power(ans,m);
cur=multiply(ans,cur);
//debug(ans,3);
//debug(cur,4);
//printf("*****************\n");
printf("%I64d\n",(cur.data[n+2][1]+mod)%mod);
}
}