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;
}


 


 
原文地址:https://www.cnblogs.com/jasonlixuetao/p/6523488.html