zoukankan      html  css  js  c++  java
  • E题:Water Problem(快速幂模板)

    题目大意:原题链接  题解链接

    解题思路:令x=x-1代入原等式得到新的等式,两式相加,将sin()部分抵消掉,得到只含有f(x)的状态转移方程f(x+1)=f(x)+f(x-2)+f(x-3),然后用矩阵快速幂即可

    #include<cstdio>
    #include<cstring>
    typedef long long ll;
    const ll mod=1e9+7;
    long long f[10];
    int temp[4]={0,1,0,-1};
    struct Mat
    {
        ll mat[4][4];
    }res;
    
    Mat Mult(Mat a,Mat b)
    {
        Mat c;
        memset(c.mat,0,sizeof(c.mat));
        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
                for(int k=0;k<4;k++)
                    c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
        return c;
    }
    Mat QMult(Mat a,ll b)
    {
        Mat t;
        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++){
                t.mat[i][j]=i==j;
            }
        }
        while(b){
            if(b&1)
                t=Mult(t,a);//注意方向,t在前,a在后 
            a=Mult(a,a);
            b>>=1;
        }
        return t;
    }
    
    int main()
    {
        int a,b,n;
        while(scanf("%d%d%d",&a,&b,&n)!=EOF){
            f[1]=a,f[2]=b;
            for(int i=3;i<=5;i++)
                f[i]=f[i-1]+f[i-2]+temp[(i-1)%4];
            if(n<=5){
                printf("%d
    ",f[n]);
                continue;
            }
            res.mat[0][0]=res.mat[0][2]=res.mat[0][3]=1;
            res.mat[1][0]=res.mat[2][1]=res.mat[3][2]=1;
            Mat ans=QMult(res,n-5);
            int anss=(ans.mat[0][0]*f[5]%mod)+(ans.mat[0][1]*f[4]%mod);
            anss=anss+(ans.mat[0][2]*f[3]%mod)+(ans.mat[0][3]*f[2]%mod);
            printf("%d
    ",anss%mod);
        }
    }
    #include<cstdio>
    #include<cstring>
    typedef long long ll;
    const ll mod=1e9+7;
    long long f[10];
    int temp[4]={0,1,0,-1};
    struct Mat
    {
        ll mat[4][4];
    }res;
    
    Mat Mult(Mat a,Mat b)
    {
        Mat c;
        memset(c.mat,0,sizeof(c.mat));
        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
                for(int k=0;k<4;k++)
                    c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
        return c;
    }
    Mat QMult(Mat a,ll b)
    {
        Mat t;
        memset(t.mat,0,sizeof(t.mat));
        t.mat[0][0]=t.mat[0][2]=t.mat[0][3]=1;
        t.mat[1][0]=t.mat[2][1]=t.mat[3][2]=1;
        while(b){
            if(b&1)
                a=Mult(t,a);
            t=Mult(t,t);
            b>>=1;
        }
        return a;
    }
    
    int main()
    {
        int a,b,n;
        while(scanf("%d%d%d",&a,&b,&n)!=EOF){
            f[1]=a,f[2]=b;
            for(int i=3;i<=5;i++)
                f[i]=f[i-1]+f[i-2]+temp[(i-1)%4];
            if(n<=5){
                printf("%d
    ",f[n]);
                continue;
            }
            res.mat[0][0]=f[5],res.mat[1][0]=f[4];
            res.mat[2][0]=f[3],res.mat[3][0]=f[2];
            Mat ans=QMult(res,n-5);
            printf("%d
    ",ans.mat[0][0]%mod);
        }
    }
  • 相关阅读:
    vue组件间传值
    Kth MIN-MAX 反演
    BZOJ4671 异或图(容斥+线性基)
    hihoCoder #1646 : Rikka with String II(容斥原理)
    字符串小结
    LOJ# 572. 「LibreOJ Round #11」Misaka Network 与求和(min25筛,杜教筛,莫比乌斯反演)
    SPOJ divcntk(min25筛)
    LA3490 Generator(KMP + 高斯消元)
    ExKMP(Z Algorithm) 讲解
    BZOJ 2728: [HNOI2012]与非(位运算)
  • 原文地址:https://www.cnblogs.com/freinds/p/6517274.html
Copyright © 2011-2022 走看看