PS寻思一小时。构造半小时。代码半小时。无限长的DEBUG。
思路:
本来天真的找到规律。想斜线走规律的。结果突然发现233....3这也太坑了!
之后知道了可以构造矩阵快速幂的形式来AC。就开始了构造之旅。。
首先:2333这种形式。因为是个素数。必定无法用一个位置构造出来。那么我们可以拆成2330+3 230+3 23+3 类似的形式。
接下来就是规律的问题了。
拿第一列
233 2333
233+a[1][0] 2333+a[1][1]
233+a[1][0]+a[2][0] 2333+a[1][1]+a[2][1]
233+a[1][0]+a[2][0]+a[3][0] .....
因为m很大。自然需要构造m的快速幂矩阵。 只要取得当前列,就可以依此来作为下一个标准进行矩阵乘法。
构造的base矩阵如下.
10 0 0 0 ... 1 //构造上个23333*10
10 1 0 0 ....1
10 1 1 0 ....1
10 1 1 1 ....1
0 0 0 0 ...1 // 补3
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
typedef long long ll;
ll mod=10000007;
struct matrix
{
ll arr[15][15];
}matrix_base,matrix_ans,temp;
int n,m;
int tt[15];
void init()
{
memset(matrix_base.arr,0,sizeof(matrix_base.arr));
matrix_base.arr[1][1]=10;
matrix_base.arr[1][n+2]=1;
for(int i=2;i<=n+1;i++)
{
matrix_base.arr[i][1]=10;
for(int j=2;j<=i;j++)
{
matrix_base.arr[i][j]=1;
}
matrix_base.arr[i][n+2]=1;
}
matrix_base.arr[n+2][n+2]=1;
memset(matrix_ans.arr,0,sizeof(matrix_ans.arr));
matrix_ans.arr[1][1]=23;
matrix_ans.arr[n+2][1]=3;
for(int i=2;i<=n+1;i++)
matrix_ans.arr[i][1]=tt[i-1];
}
matrix matrix_mulip(matrix a,matrix b)
{
memset(temp.arr,0,sizeof(temp.arr));
for(int i=1;i<=n+2;i++)
{
for(int j=1;j<=n+2;j++)
{
for(int k=1;k<=n+2;k++)
{
temp.arr[i][j]=(temp.arr[i][j]+b.arr[i][k]*a.arr[k][j])%mod;
}
}
}
return temp;
}
void matrix_pow( int x)
{
while(x)
{
if(x%2)
{
matrix_ans=matrix_mulip(matrix_ans,matrix_base);
}
matrix_base=matrix_mulip(matrix_base,matrix_base);
x=x/2;
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
cin>>tt[i];
init();
matrix_pow( m);
cout<<matrix_ans.arr[n+1][1]%mod<<endl;
}
return 0;
}