矩阵加速(数列)

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<iostream>
#define int long long
using namespace std;
const int N =2e9+1;
const int mod =1e9+7;
int T,n;
struct mat{
    int m[4][4];
}a,unit,emp,ans;
inline int read(){
    int f=0,x=0;
    char ch=getchar();
    while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
    while(isdigit(ch))  x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return f?-x:x;
}
inline mat mul(mat a,mat b){
    mat c=emp;
    for(register int i=1;i<=3;++i)
        for(register int j=1;j<=3;++j)
            for(register int k=1;k<=3;++k)
                c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
    return c;
}
inline mat power(mat a,int b){
    while(b){
        if(b&1) ans=mul(ans,a);
        a=mul(a,a);
        b>>=1;
    }
    return ans;
}
inline void debug(){
    for(register int i=1;i<=3;++i){
        for(register int j=1;j<=3;++j)
            printf("%lld ",ans.m[i][j]%mod);
        printf("\n");
    }
}
signed main(){
    T=read();
    unit.m[1][1]=1,unit.m[1][2]=1,unit.m[2][3]=1,unit.m[3][1]=1;
    for(register int i=1;i<=T;++i){
        n=read();
        if(n<=3){
            putchar(49),putchar(10);
            continue;
        }
        memset(ans.m,0,sizeof(ans.m));
        memset(a.m,0,sizeof(a.m));
        for(register int i=1;i<=3;++i) ans.m[i][i]=1;
        for(register int i=1;i<=3;++i)  a.m[1][i]=1;
        ans=power(unit,n-3);
        a=mul(a,ans);
        printf("%lld\n",a.m[1][1]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/horrigue/p/9616533.html
今日推荐