HDU6050Funny Function

来源:互联网 发布:js拼图游戏源码 编辑:程序博客网 时间:2024/06/10 11:44

题目连接

题意

​ 已知 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 longconst 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;    }}