HDU6050Funny Function

xiaoxiao2021-02-28  138

题目连接

题意

​ 已知 F1,1=F1,2=1

F1,i=F1,i1+2F1,i2

Fi,j=j+N1k=jFi1,k

​ 给出N,M,求 FM,1

分析

​ 看了官方题解才搞定的T_T,真是太菜了。

​ 可以通过归纳法发现 Fi,j=Fi,j1+2Fi,j2(j3) (最重要的推论=-=)

​ 拆解合并可以发现 jk=1Fi,k=Fi,j+1Fi,1 (j为偶数), jk=1Fi,k=Fi,j+1Fi,2+Fi,1 (j为奇数)。同时 Fi,k=ai,kFi,2+bi,kFi,1

​ 再然后就是题解中写到的,

N为偶数时: (Fi,1,Fi,2)=(Fi1,n+1Fi1,1,Fi1,n+2Fi1,2)

=(Fi1,n+1,Fi1,n+2)+(Fi1,1,Fi1,2)

=(Fi1,1,Fi1,2)An+(Fi1,1,Fi1,2)B1

=(Fi1,1,Fi1,2)(An+B1)

(Fm,1,Fm,2)=(Fi1,1,Fi1,2)(An+B1)m1

N为奇数时: (Fi,1,Fi,2)=(Fi1,n+1Fi1,2+Fi1,1,Fi1,n+22Fi1,1)

=(Fi1,n+1,Fi1,n+2)+(Fi1,2+Fi1,1,2Fi1,1)

=(Fi1,1,Fi1,2)An+(Fi1,1,Fi1,2)B2

=(Fi1,1,Fi1,2)(An+B2)

(Fm,1,Fm,2)=(Fi1,1,Fi1,2)(An+B2)m1

推出 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[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; } }
转载请注明原文地址: https://www.6miu.com/read-28466.html

最新回复(0)