题目描述
广义的斐波那契数列是指形如an=p×an−1+q×an−2an=p\times a_{n-1}+q\times a_{n-2}an=p×an−1+q×an−2的数列。今给定数列的两系数ppp和qqq,以及数列的最前两项a1a_1a1和a2a_2a2,另给出两个整数nnn和mmm,试求数列的第nnn项ana_nan除以mmm的余数。
输入格式
输入包含一行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。
思路
F(n)=p*F(n-1)+q* F(n-2)
数据量太大,还是使用矩阵加速,看一下这次的递推矩阵
|F(n),F(n-1)|=|F(n-1),F(n-2)|*|p,1||q,0| 套路简单,根据递推矩阵初始化就行了
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct no {
long long a[5][5];
no() {
memset(a,0,sizeof(a));
}
};
int p,q,a1,a2;
long long n,Mod;
no X(no a,no b) {
no c;
for(int i=1; i<=2; i++)
for(int j=1; j<=2; j++)
for(int k=1; k<=2; k++)
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%Mod;
return c;
}
no ksm(no a,long long k) {
no ans=a;
for(k--; k; k>>=1,a=X(a,a))
if(k&1)
ans=X(ans,a);
return ans;
}
int main() {
scanf("%d%d%d%d%lld%lld",&p,&q,&a1,&a2,&n,&Mod);
a1%=Mod;
a2%=Mod;
q%=Mod;
p%=Mod;
if(n<3) {
if(n==1)
printf("%d\n",a1);
else
printf("%d\n",a2);
return 0;
}
no a;
a.a[1][1]=p;
a.a[1][2]=q;
a.a[2][1]=1;
a=ksm(a,n-2);
printf("%lld\n",(a.a[1][1]*a2+a.a[1][2]*a1)%Mod);
return 0;
}