P1349 广义斐波那契数列
题目描述
广义的斐波那契数列是指形如$an=p imes a_{n-1}+q imes a_{n-2}$?的数列。今给定数列的两系数$p$和$q$,以及数列的最前两项$a_1$和$a_2$,另给出两个整数$n$和$m$,试求数列的第$n$项$a_n$除以$m$的余数。
矩阵乘法大法好,太好用了
斐波那契通项公式变成了
$F[n]=p*F[n-2]+q*F[n-1]$
那么转移矩阵也随之改变,如何求解这个转移矩阵呢?
根据通项公式以及矩阵乘法法则:
$F[n-2],F[n-1]$ <-这是一个$1*2$的初始矩阵
$F[n-1],F[n]$ <-这是一个$1*2$的结束矩阵
也就是$F[n-1],p*F[n-2]+q*F[n-1]$
矩阵运算法则:$C_{i,j}=sum A_{i,k}*B_{k,j}$
那么转移矩阵显而易见:
$0,q$
$1,p$
<-这是一个$2*2$的转移矩阵
然后矩阵快速幂就好啦。。。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define LL long long #define N 10 using namespace std; class Martix{ public: LL n,m; LL A[N][N]; Martix(){ memset(A,0,sizeof(A)); } }; LL mod; Martix operator * (Martix A,Martix B){ Martix C; int n=A.n,m=B.m,p=A.m; C.n=n,C.m=m; for(LL i=1;i<=n;i++) for(LL j=1;j<=m;j++) for(LL k=1;k<=p;k++) C.A[i][j]=(A.A[i][k]*B.A[k][j]%mod+C.A[i][j]%mod)%mod; /*for(int i=1;i<=C.n;i++) { for(int j=1;j<=m;j++) printf("%d ",C.A[i][j]); puts(""); }*/ return C; } LL p,q,a1,a2,n; Martix A,B; inline LL pow(){ for(;n;n>>=1,A=A*A) if(n&1) B=B*A; return B.A[1][2]; } int main() { scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&a1,&a2,&n,&mod); n-=2; A.n=A.m=2; A.A[1][1]=0,A.A[1][2]=q,A.A[2][1]=1,A.A[2][2]=p; B.n=1,B.m=2; B.A[1][1]=a1,B.A[1][2]=a2; printf("%lld ",pow()); return 0; }