广义斐波那契数列#
题目描述#
广义的斐波那契数列是指形如 的数列。
今给定数列的两系数 和 ,以及数列的最前两项 和 ,另给出两个整数 和 ,试求数列的第 项 对 取模后的结果。
输入格式#
输入包含一行六个整数,。
输出格式#
输出包含一行一个整数表示答案。
样例 #1#
样例输入 #1#
1 1 1 1 10 7
样例输出 #1#
6
提示#
数列第 项是 ,。
【数据范围】
对于 的数据,,。
题目分析#
题目要求的是 的值。
那么只需要求出第 n 项,再进行取余即可。题面已经提供了递推的公式 。暴力做法可以从第 3 项开始,直接一项项进行枚举递推到第 n 项即可。时间复杂度为 。但是本题的数据范围较大,直接暴力会超时,需要加速求解第 n 项的过程。
针对递推过程的加速,可以尝试使用矩阵快速幂来进行处理。
设矩阵 A 为: []。
那么意味着
结合递推式 , 可推出加速矩阵 B 为
可发现,每乘一次矩阵 B,即可向后推一项。那么求第 n 项就成了求 的第一列内容,我们可以采用矩阵快速幂在 的时间复杂度内完成求解。
代码实现#
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll p,q,a1,a2,n,M;
struct matrix{ll m[5][5];};
matrix operator *(const matrix &a,const matrix &b){
matrix c;
memset(c.m,0,sizeof(c.m));
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%M;
return c;
}
matrix fastPow(matrix a,int n){
matrix ans;
memset(ans.m,0,sizeof(ans.m));
for(int i=1;i<=2;i++) ans.m[i][i]=1;
while(n){
if(n&1) ans=ans*a;
a=a*a;
n>>=1;
}
return ans;
}
int main(){
matrix a,b;
memset(a.m,0,sizeof(a.m));
memset(b.m,0,sizeof(b.m));
cin>>p>>q>>a1>>a2>>n>>M;
a.m[1][1]=a1;a.m[1][2]=a2;
b.m[1][1]=0;b.m[1][2]=q;
b.m[2][1]=1;b.m[2][2]=p;
matrix c=a*fastPow(b,n-1);
cout<<c.m[1][1];
return 0;
}