http://acm.hdu.edu.cn/showproblem.php?pid=5015
需要构造一个 n+2 维的矩阵。
就是要增加一维去维护2333这样的序列。
可以发现 2333 = 233*10 + 3
所以增加了一维就 是1, 然后就可以全部转移了。
10 0 0 0 0 ... 1
1 1 0 0 0 ..... 0
0 1 1 0 ... 0
. . .. . .. . .. .. .. . .
0 0 0 0 0 .... 1,
矩阵乘法+快速幂优化递推。
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <bitset>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define clr0(x) memset(x,0,sizeof(x))
typedef long long LL;
const int N = 15;
const int modo = 10000007;
int k,m;
struct Matrix{
LL mat[N][N];
void unit(){
clr0(mat);
for (int i=0;i<=k;++i) mat[i][i]=1;
}
Matrix operator*(Matrix b){
Matrix c;
memset(c.mat,0,sizeof(c.mat));
for (int i=0;i<=k;++i)
for (int l=0;l<=k;++l)
if (mat[i][l])
for (int j=0;j<=k;++j)
c.mat[i][j] = (c.mat[i][j] + mat[i][l] * b.mat[l][j]) % modo;
return c;
}
};
Matrix operator^(Matrix a,int m){
Matrix t;
t.unit();
while(m){
if (m&1) t=t*a;
a=a*a;
m>>=1;
}
return t;
}
int b[15];
int main (){
while(~RD2(k,m)){
b[0] = 233;
for(int i = 1;i <= k;++i)
RD(b[i]);
b[++k] = 3;
Matrix c;
c.unit();
for(int i = 0;i < k;++i){
for(int j = 0;j < i;++j){
c.mat[i][j] = 1;
}
}
c.mat[0][0] = 10,c.mat[0][k] = 1;
// for(int i = 0;i <= k;++i){
// for(int j = 0;j <= k;++j){
// cout<<c.mat[i][j]<<' ';
// }
// cout<<endl;
// }
Matrix d = c^m;
int ans = 0;
for(int i = 0;i <= k;++i)
ans = (ans + d.mat[k-1][i] * b[i])%modo;
cout<<ans<<endl;
}
return 0;
}
浙公网安备 33010602011771号