知识储备:矩阵的应用以及快速幂
题意:
解析:
老套路,首先用列向量的形式写出项矩阵:
| f(i-1) | | f(i) |
| f(i-2) | | f(i-1) |
| i^3 | -> | (i+1)^3|
A[i-1] | i^2 | -> A[i] | (i+1)^2|
| i | | i+1 |
| 1 | | 1 |
一行一行推出乘积矩阵:
| 1 1 1 1 1 1 |
| 1 0 0 0 0 0 |
| 0 0 1 3 3 1 |
B | 0 0 0 1 2 1 |
| 0 0 0 0 1 1 |
| 0 0 0 0 0 1 |
也就是B*A[i-1]=A[i]
最后注意一下T和n都要用long long
代码:
#include<stdio.h>
#include<string.h>
#define D long long
#define N 8
const D MOD =((D)1e9+7);
struct matrix{
int size;
D mat[N][N];
matrix(int s){
size=s;memset(mat,0,sizeof(mat));
}
matrix operator * (const matrix & x)const{
matrix ans(x.size);
for(int i=1;i<=x.size;i++){
for(int j=1;j<=x.size;j++){
for(int k=1;k<=x.size;k++){
ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*x.mat[k][j])%MOD;
}
}
}return ans;
}
} ;
matrix ans(6);
void swift(matrix a,D t){
for(int i=1;i<=a.size;i++)ans.mat[i][i]=1;
while(t){
if(t&1)ans=ans*a;
a=a*a;t>>=1;
}
}
matrix f1(6);
int main(){
f1.mat[1][1]=1,f1.mat[2][1]=0,f1.mat[3][1]=8,f1.mat[4][1]=4,f1.mat[5][1]=2,f1.mat[6][1]=1;
matrix bas(6);
D tmp[7][7]={
{0,0,0,0,0,0,0},
{0,1,1,1,1,1,1},
{0,1,0,0,0,0,0},
{0,0,0,1,3,3,1},
{0,0,0,0,1,2,1},
{0,0,0,0,0,1,1},
{0,0,0,0,0,0,1}
};
for(int i=1;i<=6;i++){
for(int j=1;j<=6;j++){
bas.mat[i][j]=tmp[i][j];
}
}
D t;scanf("%lld",&t);while(t--){
D n;scanf("%lld",&n);
if(n<2)printf("%lld\n",n);
else{
swift(bas,n-1);ans=ans*f1;
printf("%lld\n",ans.mat[1][1]);
}
}
}