题目描述
广义的斐波那契数列是指形如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 }