• dutacm.club_1085_Water Problem_(矩阵快速幂)


    1085: Water Problem

    Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)
    Total Submissions:1252   Accepted:132
    [Submit][Status][Discuss]

    Description

    函数 f:Z+Z。已知 f(1)f(2) 的值,且对于任意 x>1x>1,有 f(x+1)=f(x)+f(x1)+sin(πx/2)

    求 f(n)f(n) 的值。

    Input

    多组数据。(数据组数 T100

    每组数据包含 3 个不超过 10^9 的正整数,分别代表 f(1)f(2)和 n 的值。

    Output

     输出 f(n)mod(10^9+7)。每组输出末尾有换行符。

    Sample Input

    1 2 3
    1 2 5

    Sample Output

    3
    7

    题意很清楚。题目出处:http://dutacm.club:7217/codesheaven/problem.php?id=1085
    思路:也是看的题解,之前就是最后的sin解决不了。使用此处sin函数的周期为4,那么每半个周期可以将sin抵消掉。
    f(x+1)=f(x)+f(x-1)+sin(πx/2) 1式
    f(x-1)=f(x-2)+f(x-3)
    +
    sin(π(x-2)/2) 2式
    将2式带入1式,得f(x+1)=f(x)+f(x-2)+f(x-3),然后转移矩阵很容易写出。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #include<string>
    using namespace std;
    #define MOD 1000000007
    #define LL long long
    
    int Sin[4]= {0,1,0,-1};
    struct Matrix
    {
        int row,col;
        LL matr[8][8];
        Matrix() {}
        Matrix(int r,int c,int num=0)
        {
            row=r;
            col=c;
            for(int i=1; i<=r; i++)
                for(int j=1; j<=c; j++)
                    matr[i][j]=num;
        }
    };
    
    Matrix matr_multi(Matrix m1,Matrix m2)   //矩阵乘法
    {
        Matrix m3(m1.row,m2.col,0);
        for(int i=1; i<=m1.row; i++)
            for(int j=1; j<=m2.col; j++)
                for(int k=1; k<=m1.col; k++)
                    m3.matr[i][j]=(m3.matr[i][j]+m1.matr[i][k]*m2.matr[k][j])%MOD;
        return m3;
    }
    
    void matr_givevalue(Matrix& a,Matrix b)
    {
        a.row=b.row;
        a.col=b.col;
        for(int i=1; i<=a.row; i++)
            for(int j=1; j<=a.col; j++)
                a.matr[i][j]=b.matr[i][j];
    }
    
    Matrix matr_pow(Matrix m1,int k)  //矩阵快速幂
    {
        Matrix m2;
        matr_givevalue(m2,m1);
        k--;
        while(k>0)
        {
            if(k&1)
                m2=matr_multi(m2,m1);
            m1=matr_multi(m1,m1);
            k>>=1;
        }
        return m2;
    }
    
    LL PowMod(LL n,int k)  //常规快速幂
    {
        LL res=1;
        while(k>0)
        {
            if(k&1)
                res=(res*n)%MOD;
            n=(n*n)%MOD;
            k>>=1;
        }
        return res;
    }
    
    void matr_output(Matrix m)
    {
        for(int i=1; i<=m.row; i++)
        {
            for(int j=1; j<=m.col; j++)
                cout<<m.matr[i][j]<<" ";
            cout<<endl;
        }
    }
    int main()
    {
        LL f1,f2,n;
        while(scanf("%lld%lld%lld",&f1,&f2,&n)!=EOF)
        {
            Matrix m1(1,4);
            m1.matr[1][4]=f1;
            m1.matr[1][3]=f2;
            m1.matr[1][2]=(f1+f2+Sin[2])%MOD;
            m1.matr[1][1]=(m1.matr[1][2]+m1.matr[1][3]+Sin[3])%MOD;
            Matrix m2(4,4,0);
            m2.matr[1][1]=m2.matr[1][2]=m2.matr[2][3]=m2.matr[3][1]=1;
            m2.matr[3][4]=m2.matr[4][1]=1;
            if(n>4)
            {
                m2=matr_pow(m2,n-4);
                m1=matr_multi(m1,m2);
                printf("%lld
    ",m1.matr[1][1]);
            }
            else
            {
                printf("%lld
    ",m1.matr[1][5-n]);
            }
        }
    
        return 0;
    }
    
    
    
     


     
  • 相关阅读:
    关于c语言变量的内存分布测试程序
    常用ARM指令集及汇编_破解
    CPU读取内存0x30000000地址4个字节数据
    打印十六进制字符串查看内存地址
    JZ2440串口打印字符作为调试
    搭建Linux3.4.2内核编辑环境
    网卡驱动程序
    同步互斥阻塞
    poll机制分析[转]
    安装、配置、启动FTP、SSH或NFS服务
  • 原文地址:https://www.cnblogs.com/jasonlixuetao/p/6523488.html
Copyright © 2020-2023  润新知