纯套板子题
找出列与列之间的递推关系;
|10 10 10 10 0 | | 2310 + 3 |
| 0 1 1 1 0 | | a1 + 2310 + 3 |
| 23 a1 a2 a3 3 | | 0 0 1 1 0 | = | a1+a2+2310+3 |
| 0 0 0 1 0 | |a1+a2+a3+2310+3 |
| 1 1 1 1 1 | | 3 |
嗯,就是这样 n+2个数做m次矩阵乘法
然后就没有然后了。。。。。。
上代码
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<string.h>
#define LL long long
using namespace std;
const int mod = 10000007;
struct mat
{
int m[15][15];
}unit;
int n;
void print(mat tmp)
{
printf("**************8\n");
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%d ",tmp.m[i][j]);
}
printf("\n");
}
}
mat operator * (mat a, mat b)
{
mat ret;
LL x;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
x = 0;
for(int k=0;k<n;k++)
{
x += ((LL)a.m[i][k] * b.m[k][j])%mod;
ret.m[i][j] = x%mod;
}
}
}
return ret;
}
mat pow_mat(mat a, LL x)
{
mat ret;
memset(ret.m,0,sizeof(ret.m));
for(int i=0;i<n;i++) ret.m[i][i] = 1;
while(x)
{
if(x & 1) ret = ret*a;
a = a*a;
x >>= 1;
}
return ret;
}
mat create()
{
mat tmp;
memset(tmp.m,0,sizeof(tmp.m));
for(int i = 0;i < n-1;i++) tmp.m[0][i] = 10;
for(int i = 0;i < n;i++) tmp.m[n-1][i] = 1;
for(int i=1;i<n-1;i++)
{
for(int j = i;j<n-1;j++)
{
tmp.m[i][j] = 1;
}
}
return tmp;
}
int main()
{
int a;
LL b;
while(scanf("%d%lld",&a,&b) != EOF)
{
n = a+2;
mat ans;
memset(ans.m,0,sizeof(ans.m));
ans.m[0][0] = 23;
ans.m[0][a+1] = 3;
for(int i=1;i<=a;i++)
{
scanf("%d",&ans.m[0][i]);
ans.m[0][i] %= mod;
}
//print(ans);
mat res = create();
//print(res);
res = pow_mat(res,b);
//print(res);
ans = ans * res;
//print(ans);
printf("%d\n",ans.m[0][a]);
}
}