刚好在复习dp,顺便把矩阵快速幂加速递推给复习了。
首先矩阵乘法:f[i][j]=A[i][k]*B[k][j]
我们观察斐波那契数列f[n]=f[n-1]+f[n-2],我们构造矩阵乘法
A:[ fn-2 fn-1]
B:[0 1]
[1 1]
C=A*B=[fn-1 fn-2+fn-1]=[fn-1 fn]
所以对于C[fn-1 fn],不难得出C=[f1 f2]*B^(n-2),而B是预先设置好的矩阵,于是就可以用上矩阵快速幂。
广义的斐波那契数列是指形如a(n)=p*a(n-1)+q*a(n-2)的数列。今给定数列的两系数p和q,以及数列的最前两项a(1)和a(2),另给出两个整数n和m,试求数列的第n项a(n)除以m的余数。
输入包含一行6个整数。依次是p,q,a(1),a(2),n,m,其中在p,q,a(1),a(2)整数范围内,n和m在长整数范围内。
输出包含一行一个整数,即a(n)除以m的余数。
1 1 1 1 10 7
6
【样例说明】 数列第10项是55,除以7的余数为6。
#include
using namespace std;
#define Inc(i,L,r) for(register int i=(L);i<=(r);++i)
#define Red(i,r,L) for(register int i=(r);i>=(L);--i)
#define int long long
int p,q,n,m,f1,f2;
struct Martix{
int a[10][10];
inline void init(bool flag){//可构造单位矩阵
memset(a,0,sizeof(a));
if(flag)Inc(i,1,4)a[i][i]=1;
}
};
inline Martix mul(Martix a,Martix b,int I,int J,int K,int Mod){
Martix ans;
ans.init(0);
Inc(i,1,I)Inc(j,1,J)Inc(k,1,K)(ans.a[i][j]+=(a.a[i][k]*b.a[k][j]))%=Mod;
return ans;
}
inline int quick_pow(int lm,int Mod){
Martix a;
a.a[1][1]=0;
a.a[1][2]=q;
a.a[2][1]=1;
a.a[2][2]=p;//构造矩阵A
Martix ans;
ans.init(1);
while(lm){
if(lm&1)ans=mul(ans,a,2,2,2,Mod);
a=mul(a,a,2,2,2,Mod);
lm>>=1;
}
return (ans.a[1][2]*f1+ans.a[2][2]*f2)%Mod;
}
signed main(){
scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&f1,&f2,&n,&m);
if(n==1)cout<
有时间再写吧~