链接:
HDU5015
初始矩阵:
![[1,23,a_1,a_2....a_n]](https://i-blog.csdnimg.cn/blog_migrate/36e7952170ab6a8a73110f1e4a96b2f6.gif)
递推矩阵:
over ORZ
code:
#include <cstdio>
#include <algorithm>
#include <cmath>
#define mod(x,y) ((x+y)%y)
typedef long long ll;
const ll MAXN =1e9+10;
const ll MOD = 10000007;
int n,m,a;
struct martix{ll m[14][14];}unit;
martix operator * (martix a,martix b)
{
ll x=0;
martix tmp;
for(int i=0;i<n+2;++i)
for(int j=0;j<n+2;++j)
tmp.m[i][j]=0;
for(int i=0;i<n+2;++i)
for(int j=0;j<n+2;++j)
{
x=0;
for(int k=0;k<n+2;++k)
x+=mod((a.m[i][k]*b.m[k][j]),MOD);
tmp.m[i][j]=mod(x,MOD);
}
return tmp;
}
void init()
{
for(int i=0;i<n+2;++i)
unit.m[i][i]=1;
return;
}
martix pow_quick(martix h,ll p)
{
martix tmp=unit;
while(p)
{
if(p&1)
tmp=tmp*h;
h=h*h;
p>>=1;
}
return tmp;
}
int main()
{
martix x;
{
x.m[0][0]=1,x.m[0][1]=3,x.m[0][2]=3,x.m[0][3]=3,x.m[0][4]=3,x.m[0][5]=3,x.m[0][6]=3,x.m[0][7]=3,x.m[0][8]=3,x.m[0][9]=3,x.m[0][10]=3,x.m[0][11]=3,
x.m[1][0]=0,x.m[1][1]=10,x.m[1][2]=10,x.m[1][3]=10,x.m[1][4]=10,x.m[1][5]=10,x.m[1][6]=10,x.m[1][7]=10,x.m[1][8]=10,x.m[1][9]=10,x.m[1][10]=10,x.m[1][11]=10,
x.m[2][0]=0,x.m[2][1]=0,x.m[2][2]=1,x.m[2][3]=1,x.m[2][4]=1,x.m[2][5]=1,x.m[2][6]=1,x.m[2][7]=1,x.m[2][8]=1,x.m[2][9]=1,x.m[2][10]=1,x.m[2][11]=1,
x.m[3][0]=0,x.m[3][1]=0,x.m[3][2]=0,x.m[3][3]=1,x.m[3][4]=1,x.m[3][5]=1,x.m[3][6]=1,x.m[3][7]=1,x.m[3][8]=1,x.m[3][9]=1,x.m[3][10]=1,x.m[3][11]=1,
x.m[4][0]=0,x.m[4][1]=0,x.m[4][2]=0,x.m[4][3]=0,x.m[4][4]=1,x.m[4][5]=1,x.m[4][6]=1,x.m[4][7]=1,x.m[4][8]=1,x.m[4][9]=1,x.m[4][10]=1,x.m[4][11]=1,
x.m[5][0]=0,x.m[5][1]=0,x.m[5][2]=0,x.m[5][3]=0,x.m[5][4]=0,x.m[5][5]=1,x.m[5][6]=1,x.m[5][7]=1,x.m[5][8]=1,x.m[5][9]=1,x.m[5][10]=1,x.m[5][11]=1,
x.m[6][0]=0,x.m[6][1]=0,x.m[6][2]=0,x.m[6][3]=0,x.m[6][4]=0,x.m[6][5]=0,x.m[6][6]=1,x.m[6][7]=1,x.m[6][8]=1,x.m[6][9]=1,x.m[6][10]=1,x.m[6][11]=1,
x.m[7][0]=0,x.m[7][1]=0,x.m[7][2]=0,x.m[7][3]=0,x.m[7][4]=0,x.m[7][5]=0,x.m[7][6]=0,x.m[7][7]=1,x.m[7][8]=1,x.m[7][9]=1,x.m[7][10]=1,x.m[7][11]=1,
x.m[8][0]=0,x.m[8][1]=0,x.m[8][2]=0,x.m[8][3]=0,x.m[8][4]=0,x.m[8][5]=0,x.m[8][6]=0,x.m[8][7]=0,x.m[8][8]=1,x.m[8][9]=1,x.m[8][10]=1,x.m[8][11]=1,
x.m[9][0]=0,x.m[9][1]=0,x.m[9][2]=0,x.m[9][3]=0,x.m[9][4]=0,x.m[9][5]=0,x.m[9][6]=0,x.m[9][7]=0,x.m[9][8]=0,x.m[9][9]=1;x.m[9][10]=1,x.m[9][11]=1,
x.m[10][0]=0,x.m[10][1]=0,x.m[10][2]=0,x.m[10][3]=0,x.m[10][4]=0,x.m[10][5]=0,x.m[10][6]=0,x.m[10][7]=0,x.m[10][8]=0,x.m[10][9]=0;x.m[10][10]=1,x.m[10][11]=1,
x.m[11][0]=0,x.m[11][1]=0,x.m[11][2]=0,x.m[11][3]=0,x.m[11][4]=0,x.m[11][5]=0,x.m[11][6]=0,x.m[11][7]=0,x.m[11][8]=0,x.m[11][9]=0;x.m[11][10]=0,x.m[11][11]=1;
}
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
martix tmp;
for(int i=0;i<n+2;++i)
for(int j=0;j<n+2;++j)
tmp.m[i][j]=0;
tmp.m[0][0]=1,tmp.m[0][1]=23;
for(int i=2;i<n+2;++i)
scanf("%d",&tmp.m[0][i]);
tmp=tmp*pow_quick(x,m);
/*for(int i=0;i<n+2;++i)
printf("%d ",tmp.m[0][i]);
printf("\n");*/
printf("%d\n",tmp.m[0][n+1]%10000007);
}
}
/*
1 1
1
2 2
0 0
3 7
23 47 16
*/