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;
}

浙公网安备 33010602011771号