矩阵快速幂

//https://nanti.jisuanke.com/t/A2022
#include <bits/stdc++.h>
//#define endl '\n'
#define lose {printf("NO\n");return;}
#define win {printf("YES\n");return;}
#define all(A) (A).begin(),(A).end()
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define PER(I, A, B) for (int I = (A); I >= (B); --I)
#define DB(A) cout<<(A)<<endl 
#define lson k*2
#define rson k*2+1
#define fi first
#define se second
#define PB push_back
#define Pair pair<int,int>
#define MP make_pair
#define LL long long
#define ull unsigned long long
#define int LL
using namespace std;
#define DB1(args...) do { cout << #args << " : "; dbg(args); } while (0)
void dbg() { std::cout << "  #\n"; }
template<typename T, typename...Args>
void dbg(T a, Args...args) { std::cout << a << ' '; dbg(args...); }
//var
const int maxn=2e5+10;
const int MAX=1000;
const int inf=0x3f3f3f3f;   
const int mod=1e9+7;
//head


#define NUM 9  
int MAXN=NUM;  
struct Matrix 
{  
    int a[NUM][NUM];  
    void init()           
    {  
        memset(a,0,sizeof(a));  
        for(int i=0;i<MAXN;i++)  
            a[i][i]=1;  
    }  
} A;  
Matrix mul(Matrix a,Matrix b)  //(a*b)%mod  矩阵乘法  
{  
    Matrix ans;  
    for(int i=0;i<MAXN;i++)  
        for(int j=0;j<MAXN;j++)  
        {  
            ans.a[i][j]=0;  
            for(int k=0;k<MAXN;k++)  
                ans.a[i][j]+=a.a[i][k]*b.a[k][j];  
            ans.a[i][j]%=mod;  
        }  
    return ans;  
}  

Matrix add(Matrix a,Matrix b)  //(a+b)%mod  //矩阵加法  
{  
    int i,j,k;  
    Matrix ans;  
    for(i=0;i<MAXN;i++)  
        for(j=0;j<MAXN;j++)  
        {  
            ans.a[i][j]=a.a[i][j]+b.a[i][j];  
            ans.a[i][j]%=mod;  
        }  
    return ans;  
}  

Matrix pow(Matrix a,int n)    //(a^n)%mod  //矩阵快速幂  
{  
    Matrix ans;  
    ans.init();  
    while(n)  
    {  
        if(n%2)//n&1  
            ans=mul(ans,a);  
        n/=2;  
        a=mul(a,a);  
    }  
    return ans;  
}  

Matrix sum(Matrix a,int n)  //(a+a^2+a^3....+a^n)%mod// 矩阵的幂和  
{  
    int m;  
    Matrix ans,pre;  
    if(n==1)  
        return a;  
    m=n/2;  
    pre=sum(a,m);                      //[1,n/2]  
    ans=add(pre,mul(pre,pow(a,m)));   //ans=[1,n/2]+a^(n/2)*[1,n/2]  
    if(n&1)  
        ans=add(ans,pow(a,n));          //ans=ans+a^n  
    return ans;  
}  

void output(Matrix a)//输出矩阵  
{  
    for(int i=0;i<MAXN;i++)  
        for(int j=0;j<MAXN;j++)  
            printf("%lld%c",a.a[i][j],j==MAXN-1?'\n':' ');  
}  


int n,m;
void solve()
{
	cin>>n;
	if(n == 1)  printf("3\n");
        else if(n == 2) printf("9\n");
        
        
    else
    {
    	Matrix res,ans = {
            0,0,0, 1,0,0, 1,0,0,
            1,0,0, 0,0,0, 1,0,0,
            1,0,0, 1,0,0, 1,0,0,

            0,1,0, 0,1,0, 0,0,0,
            0,1,0, 0,0,0, 0,1,0,
            0,0,0, 0,1,0, 0,1,0,

            0,0,1, 0,0,1, 0,0,1,
            0,0,1, 0,0,0, 0,0,1,
            0,0,1, 0,0,1, 0,0,0
        }; 
        //DB1(ans.a[3][2]);
        //output(ans);
        //return;
	    int ant=0;
	    res=pow(ans,n-2);
	    //output(res);
	    for(int i = 0;i < MAXN;i++)
	                for(int j = 0;j < MAXN;j++)
	                    ant = (ant + res.a[i][j]) % mod;
	   printf("%lld\n",ant);
    }
	

} 
signed main()
{
    // freopen("read.txt", "r", stdin);
    // freopen("ans.txt", "w", stdout);
    int TestCase = 1;
    cin>>TestCase;
    while (TestCase--)
    {
        solve();
    }
    char EndFile = getchar();
    EndFile = getchar();
    return 0;
}

posted on 2020-09-28 16:55  xlinsist  阅读(71)  评论(0编辑  收藏  举报