LOJ #10220. 「一本通 6.5 例 2」Fibonacci 第 n 项
题目描述
大家都知道 Fibonacci 数列吧,f1=1,f2=1,f3=2,f4=3,…,fn=fn−1+fn−2
现在问题很简单,输入 n 和 m,求 fn mod m。
输入格式
输入 n,m。
输出格式
输出fn mod m。
样例数据
样例输入
样例输出
限制与提示
对于 100% 的数据, 1≤n≤2×10^9,1≤m≤10^9+10
思路
模板题,快速幂+矩阵乘法
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; long long n,Mod; long long a[3][3],b[3][3]; long long ans[3][3],c[3][3]; void add(long long &x,long long y) { x=x+y; x-=(x>=Mod)?Mod:0; return; } int main () { a[1][1]=a[1][2]=a[2][1]=1; a[2][2]=0; ans[1][1]=ans[2][2]=1; ans[1][2]=ans[2][1]=0; scanf("%lld%lld",&n,&Mod); n--; while(n) { if(n&1) { memset(c,0,sizeof(c)); for(int i=1; i<=2; i++) for(int j=1; j<=2; j++) for(int k=1; k<=2; k++) add(c[i][j],ans[i][k]*a[k][j]%Mod); memmove(ans,c,sizeof(ans)); } memset(c,0,sizeof(c)); for(int i=1; i<=2; i++) for(int j=1; j<=2; j++) for(int k=1; k<=2; k++) add(c[i][j],a[i][k]*a[k][j]%Mod); memmove(a,c,sizeof(a)); n>>=1; } b[1][1]=1; b[1][2]=0; memset(c,0,sizeof(c)); for(int i=1; i<=2; i++) for(int j=1; j<=2; j++) for(int k=1; k<=2; k++) add(c[i][j],ans[i][k]*b[k][j]); memmove(b,c,sizeof(b)); printf("%lld\n",b[1][1]); return 0; }