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; }