洛谷P1349 广义斐波那契数列(矩阵快速幂)
P1349 广义斐波那契数列
https://www.luogu.org/problemnew/show/P1349
题目描述
广义的斐波那契数列是指形如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的余数。
输入输出样例
说明
数列第10项是55,除以7的余数为6。
矩阵快速幂求long long级斐波那契(变形)。
f[n]=a*f[n-1]+b*f[n-2], f[1]=a1,f[2]=a2, MOD=...
由得:
其他变形:
1.f(n)=a*f(n-1)+b*f(n-2)+c;(a,b,c是常数)
2.f(n)=c^n-f(n-1) ;(c是常数)
以及找循环节问题:http://blog.csdn.net/ACdreamers/article/details/25616461
前n项和:
1.当f[1]=1,f[2]=1,f[i]=f[i-1]+f[i-2](i>2)时,
S(n)=f(n+2)-1
2.推广:
本题AC代码:
#include<stdio.h> #include<string.h> #define MAX 10 typedef long long ll; ll p,q,MOD; struct mat{ ll a[MAX][MAX]; }; mat operator *(mat x,mat y) //重载*运算 { mat ans; memset(ans.a,0,sizeof(ans.a)); for(int i=1;i<=2;i++){ for(int j=1;j<=2;j++){ for(int k=1;k<=2;k++){ ans.a[i][j]+=x.a[i][k]*y.a[k][j]; ans.a[i][j]%=MOD; } } } return ans; } mat qsortMod(mat a,ll n) //矩阵快速幂 { mat t; t.a[1][1]=p;t.a[1][2]=q; //变式的系数 t.a[2][1]=1;t.a[2][2]=0; while(n){ if(n&1) a=t*a; //矩阵乘法不满足交换律,t在前 n>>=1; t=t*t; } return a; } int main() { ll a1,a2,n; scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&a1,&a2,&n,&MOD); if(n==1) printf("%lld\n",a1); else if(n==2) printf("%lld\n",a2); else{ mat a; a.a[1][1]=a2;a.a[1][2]=0; a.a[2][1]=a1;a.a[2][2]=0; //数列的前两项 a=qsortMod(a,n-2); printf("%lld\n",a.a[1][1]); } return 0; }
博文系博主原创,转载请注明出处 o(* ̄▽ ̄*)ブ 更多博文源自https://www.cnblogs.com/yzm10