我么可以整理出来这样一个式子
F[n] = f[n-2]+f[n-3]+f[n-4]
F[5] = f[1] + f[2] +f[3]
k推1 ,a数组(翻倍数组)就开k行k列,f数组就开[k]行
#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 1000000007
using namespace std;
long long a[5][5],b[5][5],f[5],c[5];
long long n,m,i,j,k,l,T;
//因为是四推一所以开四个就行 c
//--------
void kuai();
int main()
{
scanf("%d",&T);
for(i = 1;i <= T; i++)
{
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
scanf("%d",&n);
a[1][2] = a[2][3] = a[3][4] = 1;
a[4][1] = a[4][2] = a[4][3] = 1;
f[1] = f[2] = f[3] = 1;
f[4] = 2;
if(n <= 3 )
{
cout<<1<<endl;
continue;
}
n -= 4;
kuai();
cout<<f[4]<<endl;
}
return 0;
}
void kuai()
{
int i,j,k;
while(n > 0)
{
if(n % 2 == 1)
{
memset(c,0,sizeof(c));
for(i = 1; i <= 4; i++)
for(j = 1;j <= 1; j++)
for(k = 1;k <= 4; k++)
c[i] = (c[i] + a[i][k]*f[k])%inf;
for(i = 1;i <= 4; i++)
f[i] = c[i];
}
memset(b,0,sizeof(b));
for(i = 1;i <= 4; i++)
for(j = 1;j <= 4; j++)
for(k = 1;k <= 4; k++)
b[i][j] = (b[i][j] + a[i][k]*a[k][j])%inf;
for(i = 1;i <= 4; i++)
for(j = 1;j <= 4; j++)
a[i][j] = b[i][j];
n /= 2;
}
}