題意
已知
給出N,M,求
分析
看了官方題解才搞定的T_T,真是太菜了。
可以通過歸納法發現
拆解合並可以發現
再然後就是題解中寫到的,
N爲偶數時:
N爲奇數時:
推出
代碼
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define LL long long
const int mod=1e9+7;
const long long N = 3;
LL t,b,c,f1,f2;
struct Node { //矩陣
long long line,cal;
long long a[3][3];
Node(){
line=3,cal=3;
a[0][0] = 0; a[0][1] = 2; a[0][2] = 0;
a[1][0] = 0; a[1][1] = 2; a[1][2] = 1;
a[2][0] = 0; a[2][1] = 0; a[2][2] = -1;
}
friend Node operator+(Node &A,Node &B){
Node ret;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
ret.a[i][j]=((A.a[i][j]+B.a[i][j])%mod+mod)%mod;
return ret;
}
}I,B1,B2;
Node Matlab(Node x,Node s) { //矩陣乘法
Node ans;
ans.line = x.line,ans.cal = s.cal;
memset(ans.a,0,sizeof(ans.a));
for(long long i=0;i<x.line;i++) {
for(long long j=0;j<x.cal;j++) {
if(x.a[i][j]!=0)
for(long long k=0;k<s.cal;k++) {
ans.a[i][k] += x.a[i][j]*s.a[j][k];
ans.a[i][k]=((ans.a[i][k]+mod)%mod+mod)%mod;
}
}
}
return ans;
}
Node Fast_Matrax(Node tmp,LL b) { //矩陣快速冪
Node ans=I;
while(b){
if(b&1)
ans=Matlab(ans,tmp);
b>>=1;
tmp=Matlab(tmp,tmp);
}
return ans;
}
int main() {
for(int i=0;i<3;++i)
for(int j=0;j<3;++j){
if(i==j)
I.a[i][j]=1;
else
I.a[i][j]=0;
B1.a[i][j]=B2.a[i][j]=0;
}
B1.a[0][0]=-1;B1.a[0][1]=0;B1.a[0][2]=0;
B1.a[1][0]=0;B1.a[1][1]=-1;B1.a[1][2]=0;
B2.a[0][0]=1;B2.a[0][1]=-1;B2.a[0][2]=0;
B2.a[1][0]=-2;B2.a[1][1]=0;B2.a[1][2]=0;
int T;
LL n,m;
cin>>T;
while(T--){
cin>>n>>m;
Node A,tmp,tmp2;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
A.a[i][j]=0;
if(n==1 || m==1){
printf("1\n");
continue;
}
tmp=Fast_Matrax(tmp,n-1);
A.a[0][0]=((tmp.a[0][1]-tmp.a[0][2])%mod+mod)%mod;
A.a[0][1]=((tmp.a[1][1]-tmp.a[1][2])%mod+mod)%mod;
tmp=Node();
tmp=Fast_Matrax(tmp,n);
A.a[1][0]=((tmp.a[0][1]-tmp.a[0][2])%mod+mod)%mod;
A.a[1][1]=((tmp.a[1][1]-tmp.a[1][2])%mod+mod)%mod;
if(n&1)
A=A+B2;
else
A=A+B1;
A=Fast_Matrax(A,m-1);
LL ans=((A.a[0][0]+A.a[0][1])%mod+mod)%mod;
cout<<ans<<endl;
}
}