P1349 广义斐波那契数列 题解

题目传送门

题目

题目描述

广义的斐波那契数列是指形如 $a_n=p\times a_{n-1}+q\times a_{n-2}$ 的数列。
今给定数列的两系数 $p$ 和 $q$,以及数列的最前两项 $a_1$ 和$ a_2$,另给出两个整数 $n$ 和 $m$,试求数列的第 $n$ 项 $a_n \bmod m$。

输入格式

输入包含一行六个整数,$p,q,a_1,a_2,n,m$。

输出格式

输出包含一行一个整数表示答案。

样例 #1

样例输入 #1

1 1 1 1 10 7

样例输出 #1

6

提示

数列第 $10 $项是 $55$,$55 \bmod 7 = 6$。

【数据范围】
对于 $100\%$ 的数据,$p,q,a_1,a_2 \in [0,2^{31}-1]$,$1\le n,m \le 2^{31}-1$。

题解

要求解广义斐波那契数列,我们需要先从普通斐波那契数列数列讲起

求解斐波那契数列

通常情况下,我们遇到的斐波那契数列是三项递推的形式:

$$F_{i+2}=F_{i+1}+F_{i}$$

当然,你可以递推求解$F_n$,但是如果$n$过大,你就炸了。但是我们可以使用矩阵加速。矩阵是什么?矩阵加速又是什么?详情看这个文章:《矩阵》

设$Fib(n)$表示一个$1\times 2$​的矩阵$\begin{bmatrix} F_{n} & F_{n-1} \end{bmatrix}$,那么我们就需要将它与一个矩阵相乘,得到$Fib(n+1)$,根据矩阵的计算方法,你可以得到这个要乘的矩阵:$\begin{bmatrix}
1 & 1 \\
1 & 0
\end{bmatrix}$

,你可以计算模拟一下:

$$\begin{aligned}\begin{bmatrix}F_{n+1} & F_{n-1}\end{bmatrix}&=\begin{bmatrix}F_{n} & F_{n-1}\end{bmatrix}\times \begin{bmatrix}1 & 1 \\1 & 0\end{bmatrix} \\& =\begin{bmatrix}F_{n}+F_{n-1} & F_{n}\end{bmatrix}\end{aligned}$$

于是,从$Fib(2)$开始,每次乘上一个相同的矩阵,就可以求解下一个递推项,所以使用矩阵快速幂就能求解$Fib(n)$。

求解广义斐波那契数列

巧妙地转化条件与结论,根据上述规则,我们可以确定下矩阵$\begin{bmatrix}p & 1 \\q & 0\end{bmatrix}$是矩阵快速幂的底数,将上面的公式中的$\begin{bmatrix}1 & 1 \\1 & 0\end{bmatrix}$换成新的式子即可。

代码

代码中$Fib(n)$表示为$\begin{bmatrix}
F_{n-1} & F_{n}
\end{bmatrix}$,与题解内容稍有不同。

Fast 命名空间中包括快读、快输、各种宏定义,不会影响代码阅读,您可以在左侧栏文章《代码模板》中查看具体内容。

#include<bits/stdc++.h>
using namespace std;
namespace Fast{...}
using namespace Fast;
ll p,q,A[M],n,m;
struct matrix{
    ll m[101][101],c,r;
    matrix(){
        memset(m,0,sizeof(m));
    }
    void matrix_read(){
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++)
                read(m[i][j]);
        return;
    }
    void matrix_print(){
        for(int i=1;i<=r;i++){
            for(int j=1;j<=c;j++){
                print(m[i][j]);
                space;
            }
            enter;
        }
        return;
    }
}a,ans;
matrix operator *(const matrix &x,const matrix &y){
    matrix c;
    int co=x.c,ro=y.r;
    c.c=co,c.r=ro;
    for(int i=1;i<=ro;i++)
        for(int j=1;j<=co;j++)
            for(int k=1;k<=co;k++)
                c.m[i][j]=(c.m[i][j]+x.m[i][k]*y.m[k][j])%m;
    return c;
}
matrix matrix_pow(matrix x,ll num){
    matrix pow_ans;
    pow_ans.c=pow_ans.r=2;
    memset(pow_ans.m,0,sizeof(pow_ans.m));
    for(int i=1;i<=2;i++)   pow_ans.m[i][i]=1;
    while(num){
        if(num&1)   pow_ans=pow_ans*x;
        x=x*x;
        num>>=1;
    }
    return pow_ans;
}
int main(){
    read(p,q,A[1],A[2],n,m);
    a.m[1][1]=0;
    a.m[1][2]=1;
    a.m[2][1]=q;
    a.m[2][2]=p;
    ans.c=ans.r=a.c=a.r=2;
    ans=matrix_pow(a,n-2);
    print((ans.m[2][1]*A[1]+ans.m[2][2]*A[2])%m);
    return 0;
}
文章标题:P1349 广义斐波那契数列 题解
文章链接:https://www.laoguantx.top/p1349-%e5%b9%bf%e4%b9%89%e6%96%90%e6%b3%a2%e9%82%a3%e5%a5%91%e6%95%b0%e5%88%97-%e9%a2%98%e8%a7%a3.html
文章内容仅供参考,其中可能会有部分内容参考、引用其他网站,转发请务必标注作者为 “老官童鞋gogo” ,原文链接为 https://www.laoguantx.top/p1349-%e5%b9%bf%e4%b9%89%e6%96%90%e6%b3%a2%e9%82%a3%e5%a5%91%e6%95%b0%e5%88%97-%e9%a2%98%e8%a7%a3.html 。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇