51Nod 1341 混合序列(矩阵快速幂)

来源:互联网 发布:java加密软件 编辑:程序博客网 时间:2024/06/11 15:47

这里写图片描述

思路:把f(n)展开有
f(n)=a0bn+a1bn1+a2bn2++anb0

再写出n-1

f(n1)=a0bn1+a1bn2+a2bn3++an1b0

我们让f(n-1)*q得到

f(n1)q=a0bn+a1bn1+a2bn2++an1b1

发现与f(n)项相差了anb0所以有

f(n)=f(n1)q+anb0

an=an1p+r所以有

f(n)=f(n1)q+an1pb0+rb0

得到递推公式我们就可以写出矩阵了


(f(n) an r)=q00pb0p0b011f(n1)an1r
递推就是
(f(n) an r)=q00pb0p0b011n1f(1)a1r

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX 3#define mod 1000000007using namespace std;typedef struct {long long m[MAX][MAX];}Matrix;Matrix P={0};Matrix I={1,0,0,0,1,0,0,0,1};Matrix Matrixmul(Matrix a,Matrix b){    int i,j,k;    Matrix c;    for(i=0;i<MAX;i++)        for(j=0;j<MAX;j++)        {            c.m[i][j]=0;            for(k=0;k<MAX;k++)            {                c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;            }            c.m[i][j]%=mod;        }        return c;}Matrix quickpow(long long n){    Matrix m=P,b=I;    while(n>0)    {        if(n%2==1)            b=Matrixmul(b,m);        n=n/2;        m=Matrixmul(m,m);    }    return b;}int main(){    long long p,q,r,n;    while(scanf("%lld%lld%lld%lld",&p,&q,&r,&n)!=EOF)    {        P.m[0][0]=q;        P.m[0][1]=3*p;        P.m[0][2]=3;        P.m[1][1]=p;        P.m[1][2]=1;        P.m[2][2]=1;        Matrix a;        a=quickpow(n-1);        printf("%lld\n",(a.m[0][0]*3*r%mod+(a.m[0][1]+a.m[0][2])*r%mod)%mod);    }    return 0;}
原创粉丝点击