题目大意
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
答案矩阵[111]开始,三个为一组,然后特征矩阵⎡⎣⎢101111112⎤⎦⎥ 。乘一次就会出三项,然后处理一下n%3就行,主要是矩阵的构造。
#include <cstdio>
#include <algorithm>
#include <cstring>
#define Rep(i,s,t) for(int i=s;i<=t;i++)
using namespace std;
typedef long long LL;
const LL p = 1000000007;
LL n;
int T;
namespace matrix_mul{
struct matrix{
LL x[5][5];
}Ans,tmp,mimi;
matrix mul(matrix a,LL a1,matrix b,LL b1){
matrix tmp;
memset(tmp.x,0,sizeof(tmp.x));
Rep(i,1,a1) Rep(j,1,b1) Rep(k,1,3)
tmp.x[i][j] = (tmp.x[i][j]+a.x[i][k]*b.x[k][j])%p;
return tmp;
}
matrix power(matrix a,matrix b,LL n){
matrix ans = a,tmp = b;
for(LL i=n-1;i;i>>=1){
if(i & 1) ans = mul(ans,1,tmp,3);
tmp = mul(tmp,3,tmp,3);
}
return ans;
}
}
int main(){
using namespace matrix_mul;
scanf("%d",&T);
Ans.x[1][1]=Ans.x[1][2]=Ans.x[1][3]=1;
tmp.x[1][1]=tmp.x[1][2]=tmp.x[1][3]=tmp.x[2][2]=tmp.x[2][3]=tmp.x[3][1]=tmp.x[3][2]=1;
tmp.x[2][1]=0;tmp.x[3][3]=2;
while( T-- ){
scanf("%lld",&n);
if(n%3==0)
mimi = power(Ans,tmp,n/3);
else
mimi = power(Ans,tmp,n/3+1);
printf("%lld\n",n%3==0? mimi.x[1][3]:mimi.x[1][n%3]);
}
return 0;
}