题解:矩阵快速幂
我们可以令左上角为23,那么可以推得下一列为:
由此我们可以得到转移矩阵
T
T
T=
[
10
0
0
0
⋯
1
10
1
0
0
⋯
1
10
1
1
0
⋯
1
⋮
⋮
⋮
⋮
⋱
1
0
0
0
0
⋯
1
]
\left[ \begin{matrix} 10 & 0&0&0&\cdots&1 \\ 10 & 1&0&0&\cdots&1 \\ 10 & 1&1&0&\cdots&1 \\ \vdots &\vdots& \vdots& \vdots&\ddots&1\\ 0&0&0&0&\cdots&1\\ \end{matrix} \right]
⎣⎢⎢⎢⎢⎢⎡101010⋮0011⋮0001⋮0000⋮0⋯⋯⋯⋱⋯11111⎦⎥⎥⎥⎥⎥⎤
因为要多存储个位的3,所以我们将矩阵扩成(n+1) * (n+1),初始矩阵
A
A
A同理。
那么第
m
m
m列就是
A
∗
T
A*T
A∗T
m
m
m,取第
n
n
n行即可。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
const int mod = 1e7 + 7;
int n, m, a[15];
struct matrix {
ll mat[12][12];
matrix() { memset(mat, 0, sizeof(mat)); }
matrix operator * (const matrix& b)const {
matrix ans;
for (int i = 0; i <= n + 1; i++) {
for (int j = 0; j <= n + 1; j++) {
ans.mat[i][j] = 0;
for (int k = 0; k <= n + 1; k++) {
ans.mat[i][j] = (ans.mat[i][j] + mat[i][k] * b.mat[k][j] % mod + mod) % mod;
}
}
}
return ans;
}
};
matrix q_pow(matrix a, ll b) {
matrix ans;
memset(ans.mat, 0, sizeof(ans.mat));
for (int i = 0; i <= n + 1; i++) ans.mat[i][i] = 1;
while (b) {
if (b & 1) ans = ans * a;
b >>= 1;
a = a * a;
}
return ans;
}
int main() {
while (~scanf("%d%d", &n, &m)) {
a[0] = 23;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
a[n + 1] = 3;
matrix ma;
for (int i = 0; i <= n; i++) {
ma.mat[i][0] = 10;
ma.mat[i][n + 1] = 1;
for (int j = 1; j <= i; j++) ma.mat[i][j] = 1;
}
ma.mat[n + 1][n + 1] = 1;
ma = q_pow(ma, m);
ll ans = 0;
for (int i = 0; i <= n + 1; i++) {
ans = (ans + ma.mat[n][i] * a[i]) % mod;
}
printf("%lld\n", ans);
}
return 0;
}