渐渐有点理解矩阵的含义了
多刷多思考!
主要是利用矩阵来转移状态,通过矩阵乘法来得出结果,要先推出矩阵的转移形式
之后的乘法和快速幂就很套路了。
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int mod = 1e7+7;
int n,m;
struct matrix { //定义矩阵结构体并且初始化数组
long long m[15][15]; //注意要定义为long long ,不然会爆
matrix() {
memset(m,0,sizeof(m));
}
};
matrix mul(matrix a,matrix b) { //矩阵乘法
matrix tmp;
for(int i = 1;i <= n+2;i++) {
for(int j = 1;j <= n+2;j++) {
for(int k = 1;k <= n+2;k++) {
tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % mod; //每次取模
}
}
}
return tmp;
}
matrix powmul(matrix a,int x) { //矩阵快速幂
matrix tmp;
for(int i = 1;i <= n+2;i++)
tmp.m[i][i] = 1; //别忘记定义单位矩阵!
while(x) {
if(x & 1)
tmp = mul(tmp,a);
a = mul(a,a);
x >>= 1;
}
return tmp;
}
void pi(matrix x) {
for(int i = 1;i <= n+2;i++) {
for(int j = 1;j <= n+2;j++) {
printf("%d ",x.m[i][j]);
}
printf("\n");
}
printf("\n");
}
int main() {
while(scanf("%d%d",&n,&m) != EOF) {
matrix ans,base; //如果是使用结构体内部函数初始化数组的话要在main函数内定义变量,这样才能每次都初始化结构体内的数组
ans.m[1][1] = 23;
for(int i = 2;i <= n+1;i++)
scanf("%lld",&ans.m[i][1]);
ans.m[n+2][1] = 3;
for(int i = 1;i <= n+1;i++)
base.m[i][1] = 10;
for(int i = 1;i <= n+2;i++)
base.m[i][n+2] = 1;
for(int i = 2;i <= n+1;i++)
for(int j = 2;j <= i;j++)
base.m[i][j] = 1;
base = powmul(base,m);
ans = mul(base,ans);
//pi(ans); //输出检查结果
//pi(base);
printf("%lld\n",ans.m[n+1][1]);
}
return 0;
}