[洛谷P1349]广义斐波那契数列

Posted Mrsrz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[洛谷P1349]广义斐波那契数列相关的知识,希望对你有一定的参考价值。

题目大意:设$f[n]=f[n-1]*p+f[n-2]*q(当n>2时)$,给你p,q,f[1],f[2],n,m,求f[n]mod m的值。

解题思路:明显,递推是会TLE的,我们又得用矩阵加速大法了。

于是就很简单了。

$$\\begin{bmatrix}f[n-1]\\\\f[n]\\end{bmatrix}\\quad=\\begin{bmatrix}0&1\\\\q&p\\end{bmatrix}^{n-2}\\quad ×\\begin{bmatrix}f[0]\\\\f[1]\\end{bmatrix}\\quad$$

时间复杂度$O(\\log_2 n)$

C++ Code:

#include<cstdio>
#include<cstring>
using namespace std;
int P,Q,a1,a2,n,m;
struct mat{
    long long a[30][30];
    int r,c;
};
mat mul(mat x,mat y){
    mat ans;
    memset(&ans,0,sizeof ans);
    for(int i=0;i<x.r;++i)
    for(int j=0;j<y.c;++j)
    for(int k=0;k<x.c;++k)
    ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j])%m;
    ans.r=x.r;
    ans.c=y.c;
    return ans;
}
void pow(int n){
    mat p;
    memset(&p,0,sizeof p);
    p.r=p.c=2;
    p.a[0][1]=1;
    p.a[1][0]=Q;
    p.a[1][1]=P;
    mat ans;
    memset(&ans,0,sizeof ans);
    ans.r=ans.c=2;
    ans.a[0][0]=ans.a[1][1]=1;
    while(n){
        if(n&1){
            ans=mul(p,ans);
        }
        p=mul(p,p);
        n>>=1;
    }
    p.a[0][0]=a1%m;
    p.a[1][0]=a2%m;
    p.c=1;
    ans=mul(ans,p);
    printf("%d\\n",(int)ans.a[1][0]);
}
int main(){
	scanf("%d%d%d%d%d%d",&P,&Q,&a1,&a2,&n,&m);
    if(n==1)printf("%d\\n",a1%m);else
    if(n==2)printf("%d\\n",a2%m);else
    pow(n-2);
    return 0;
}

 

以上是关于[洛谷P1349]广义斐波那契数列的主要内容,如果未能解决你的问题,请参考以下文章

洛谷——P1349 广义斐波那契数列

[洛谷P1349]广义斐波那契数列

P1349 广义斐波那契数列(矩阵乘法)

P1349 广义斐波那契数列

P1349 广义斐波那契数列

矩阵乘法快速幂 codevs 1574 广义斐波那契数列