传送门:题目连接
思路:一看到n的数据范围和斐波那契,典型的矩阵快速幂,那么该这么构造呢?可见主要就是后面那个i^3 + i^2 + i^1 + 1这个地方有点难构造,其实不然,仔细算一下就会发现,i^3 = (i-1)^3 +3(i-1)^2 + 3(i-1) + 1 同理可以得到i^2 ,i 和1 所以构造函数就出来了,那么这题也就简单了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<stack>
#define eps 1e-7
#define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define say printf
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
const int mod = 1000000007;
struct Mat{
ll a[6][6]; //会爆int的。
};
ll n;
Mat mul(Mat A, Mat B){
Mat C;
memset(C.a,0,sizeof(C.a));
for(int i=0;i<6;i++){
for(int k=0;k<6;k++){
for(int j=0;j<6;j++){
C.a[i][j] = (C.a[i][j]+A.a[i][k]*B.a[k][j])%mod;
}
}
}
return C;
}
Mat pow(Mat A,ll n){
Mat B;
memset(B.a,0,sizeof(B.a));
for(int i=0;i<6;i++){
B.a[i][i] = 1;
}
while(n>0){
if(n&1) B = mul(B,A);
A = mul(A,A);
n >>= 1;
}
return B;
}
void solve(){
Mat res;
memset(res.a,0,sizeof(res.a));
for(int i=0;i<6;i++) res.a[0][i] = 1;
for(int i=1;i<6;i++) res.a[1][i] = 0;
res.a[1][0] = 1;
res.a[2][0] = 0;res.a[2][1] = 0;res.a[2][2] = 1;
res.a[2][3] = 3;res.a[2][4] = 3;res.a[2][5] = 1;
res.a[3][0] = 0;res.a[3][1] = 0;res.a[3][2] = 0;
res.a[3][3] = 1;res.a[3][4] = 2;res.a[3][5] = 1;
res.a[4][0] = 0;res.a[4][1] = 0;res.a[4][2] = 0;
res.a[4][3] = 0;res.a[4][4] = 1;res.a[4][5] = 1;
res.a[5][0] = 0;res.a[5][1] = 0;res.a[5][2] = 0;
res.a[5][3] = 0;res.a[5][4] = 0;res.a[5][5] = 1;
res = pow(res,n-1);
int sum=(res.a[0][0]*1 + res.a[0][1]*0 + res.a[0][2]*8 + res.a[0][3]*4 + res.a[0][4]*2 + res.a[0][5])%mod;
printf("%d\n",sum);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%lld",&n);
solve();
}
return 0;
}