ACM-ICPC 2018 焦作賽區網路預賽 Poor God Water (水題+矩陣快速冪)
阿新 • • 發佈:2018-12-24
#include<bits/stdc++.h> using namespace std; #define debug puts("YES"); #define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++) #define read(x,y) scanf("%d%d",&x,&y) #define lrt int l,int r,int rt #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define ll long long const int maxn =2e5+5; const int mod=1e9+7; /* 不要被啥公式嚇到, 老老實實的先把 11 21 31 12 22 32 13 23 33 狀壓成1到9然後推公式, 最後對九個式子用矩陣快速冪即可, 這道題就怕陷入推公式的怪圈。。。。 */ ll tp[9][9]=///遞推公式 { 0,0,0,1,0,0,1,0,0, 1,0,0,1,0,0,0,1,0, 1,0,0,1,0,0,0,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,0, 0,0,1,0,0,0,0,0,1, 0,0,0,0,0,1,0,0,1, 0,0,1,0,0,1,0,0,0 }; struct jz { ll a[9][9]; jz() { memset(a,0,sizeof(a)); } jz operator*( jz y) { jz ans; for(int i=0;i<9;i++) for(int j=0;j<9;j++) { ans.a[i][j]=0; for(int k=0;k<9;k++) ans.a[i][j]=(ans.a[i][j]+a[i][k]%mod*y.a[k][j]%mod)%mod; } return ans; } }; jz unit; ll fpow(ll n) { jz ans,shu; for(int i=0;i<9;i++) for(int j=0;j<9;j++) shu.a[i][j]=tp[i][j]; for(ans=unit;n;n>>=1,shu=shu*shu) if(n&1) ans=shu*ans;///矩陣快速冪 ll ret=0; for(int i=0;i<9;i++) for(int j=0;j<9;j++) ret=(ret+ans.a[i][j])%mod; return ret; } int main() { for(int i=0;i<9;i++) unit.a[i][i]=1; int t;scanf("%d",&t); ll n; while(t--) { scanf("%lld",&n); if(n==1) puts("3"); else if(n==2) puts("9"); else printf("%lld\n",fpow(n-2)%mod); } return 0; }