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

这里写图片描述

思路:把f(n)展开有
f ( n ) = a 0 b n + a 1 b n − 1 + a 2 b n − 2 + ⋯ + a n b 0 f\left ( n \right )=a_{0}b_{n}+a_{1}b_{n-1}+a_{2}b_{n-2}+\cdots +a_{n}b_{0} f(n)=a0bn+a1bn1+a2bn2++anb0

再写出n-1

f ( n − 1 ) = a 0 b n − 1 + a 1 b n − 2 + a 2 b n − 3 + ⋯ + a n − 1 b 0 f\left ( n-1 \right )=a_{0}b_{n-1}+a_{1}b_{n-2}+a_{2}b_{n-3}+\cdots +a_{n-1}b_{0} f(n1)=a0bn1+a1bn2+a2bn3++an1b0

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

f ( n − 1 ) q = a 0 b n + a 1 b n − 1 + a 2 b n − 2 + ⋯ + a n − 1 b 1 f\left ( n-1 \right )q=a_{0}b_{n}+a_{1}b_{n-1}+a_{2}b_{n-2}+\cdots +a_{n-1}b_{1} f(n1)q=a0bn+a1bn1+a2bn2++an1b1

发现与f(n)项相差了 a n b 0 a_{n}b_{0} anb0所以有

f ( n ) = f ( n − 1 ) q + a n b 0 f\left ( n \right )=f\left ( n-1 \right )q+a_{n}b_{0} f(n)=f(n1)q+anb0

a n = a n − 1 p + r a_{n}=a_{n-1}p+r an=an1p+r所以有

f ( n ) = f ( n − 1 ) q + a n − 1 p b 0 + r b 0 f\left ( n \right )=f\left ( n-1 \right )q+a_{n-1}pb_{0}+rb_{0} f(n)=f(n1)q+an1pb0+rb0

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


( f ( n ) a n r ) = ( q p b 0 b 0 0 p 1 0 0 1 ) ( f ( n − 1 ) a n − 1 r ) \begin{pmatrix} f(n)\\ a_{n}\\ r \end{pmatrix}=\begin{pmatrix} q &pb_{0} &b_{0} \\ 0 &p &1 \\ 0 & 0 &1 \end{pmatrix}\begin{pmatrix} f(n-1)\\ a_{n-1}\\ r \end{pmatrix} f(n)anr=q00pb0p0b011f(n1)an1r
递推就是
( f ( n ) a n r ) = ( q p b 0 b 0 0 p 1 0 0 1 ) n − 1 ( f ( 1 ) a 1 r ) \begin{pmatrix} f(n)\\ a_{n}\\ r \end{pmatrix}=\begin{pmatrix} q &pb_{0} &b_{0} \\ 0 &p &1 \\ 0 & 0 &1 \end{pmatrix}^{n-1}\begin{pmatrix} f(1)\\ a_{1}\\ r \end{pmatrix} f(n)anr=q00pb0p0b011n1f(1)a1r

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 3
#define mod 1000000007
using 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值