title

矩阵快速幂

#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;
}
posted @ 2018-09-10 01:26  Horrigue_JyowYang  阅读(69)  评论(0编辑  收藏  举报