P1349 广义斐波那契数列

Posted five20

tags:

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

题目描述

广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列。今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an除以m的余数。

输入输出格式

输入格式:

输入包含一行6个整数。依次是p,q,a1,a2,n,m,其中在p,q,a1,a2整数范围内,n和m在长整数范围内。

输出格式:

输出包含一行一个整数,即an除以m的余数。

输入输出样例

输入样例#1: 
1 1 1 1 10 7
输出样例#1: 
6

说明

数列第10项是55,除以7的余数为6。

 

Solution:

  本题基本算是一道矩阵加速模板了,直接构造一手矩阵:

   \begin{bmatrix} a2& a1\end{bmatrix} 以及中间矩阵 \begin{bmatrix} p & 1 \\ q & 0 \end{bmatrix}

代码:

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 #define mem(p) memset(&p,0,sizeof(p))
 5 using namespace std;
 6 ll pp,q,a1,a2,n,m;
 7 struct mat{ll a[3][3],r,c;};
 8 il mat mul(mat x,mat y)
 9 {
10     mat p;
11     mem(p);
12     for(int i=0;i<x.r;i++)
13         for(int j=0;j<y.c;j++)
14             for(int k=0;k<x.c;k++)
15     p.a[i][j]=(p.a[i][j]+x.a[i][k]*y.a[k][j])%m;
16     p.r=x.r,p.c=y.c;
17     return p;
18 }
19 il void fast(ll k)
20 {
21     mat p,ans;
22     mem(p),mem(ans);
23     p.r=p.c=2;
24     p.a[0][0]=pp,p.a[0][1]=1,p.a[1][0]=q;
25     ans.r=1,ans.c=2;
26     ans.a[0][0]=a2,ans.a[0][1]=a1;
27     while(k)
28     {
29         if(k&1)ans=mul(ans,p);
30         k>>=1;
31         p=mul(p,p);
32     }
33     cout<<ans.a[0][0];
34 }
35 int main()
36 {
37     ios::sync_with_stdio(0);
38     cin>>pp>>q>>a1>>a2>>n>>m;
39     if(n==1)cout<<a1%m;
40     else if(n==2)cout<<a2%m;
41     else fast(n-2);
42     return 0;
43 }

 

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

P1349 广义斐波那契数列

洛谷P1349 广义斐波那契数列(矩阵快速幂)

P1349 广义斐波那契数列

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

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

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