题目连接
题意
已知
F1,1=F1,2=1
F1,i=F1,i−1+2F1,i−2
Fi,j=∑j+N−1k=jFi−1,k
给出N,M,求
FM,1
分析
看了官方题解才搞定的T_T,真是太菜了。
可以通过归纳法发现
Fi,j=Fi,j−1+2Fi,j−2(j≥3)
(最重要的推论=-=)
拆解合并可以发现
∑jk=1Fi,k=Fi,j+1−Fi,1
(j为偶数),
∑jk=1Fi,k=Fi,j+1−Fi,2+Fi,1
(j为奇数)。同时
Fi,k=ai,kFi,2+bi,kFi,1
再然后就是题解中写到的,
N为偶数时:
(Fi,1,Fi,2)=(Fi−1,n+1−Fi−1,1,Fi−1,n+2−Fi−1,2)
=(Fi−1,n+1,Fi−1,n+2)+(−Fi−1,1,−Fi−1,2)
=(Fi−1,1,Fi−1,2)An+(Fi−1,1,Fi−1,2)B1
=(Fi−1,1,Fi−1,2)(An+B1)
(Fm,1,Fm,2)=(Fi−1,1,Fi−1,2)(An+B1)m−1
N为奇数时:
(Fi,1,Fi,2)=(Fi−1,n+1−Fi−1,2+Fi−1,1,Fi−1,n+2−2Fi−1,1)
=(Fi−1,n+1,Fi−1,n+2)+(−Fi−1,2+Fi−1,1,−2Fi−1,1)
=(Fi−1,1,Fi−1,2)An+(Fi−1,1,Fi−1,2)B2
=(Fi−1,1,Fi−1,2)(An+B2)
(Fm,1,Fm,2)=(Fi−1,1,Fi−1,2)(An+B2)m−1
推出
A,B1,B2
,套一下矩阵快速幂即可。
代码
#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[
1][
0] =
0
a[
2][
0] =
0
}
friend Node operator+(Node &
A,Node &B){
Node ret
for(int i=
0
for(int j=
0
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
for(long long j=
0
if(x.
a[i][j]!=
0)
for(long long k=
0
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
for(int j=
0
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[
1][
0]=
0
B2.
a[
0][
0]=
1
B2.
a[
1][
0]=-
2
int T
LL n,m
cin>>T
while(T--){
cin>>n>>m
Node
A,tmp,tmp2
for(int i=
0
for(int j=
0
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
}
}