Luogu1306 斐波那契公約數
阿新 • • 發佈:2018-11-06
原題連結:https://www.luogu.org/problemnew/show/P1306
斐波那契公約數
題目描述
對於Fibonacci數列:1,1,2,3,5,8,13…大家應該很熟悉吧~~~但是現在有一個很“簡單”問題:第n項和第m項的最大公約數是多少?
Update:加入了一組資料。
輸入輸出格式
輸入格式:
兩個正整數n和m。(n,m<=10^9)
注意:資料很大
輸出格式:
Fn和Fm的最大公約數。
由於看了大數字就頭暈,所以只要輸出最後的8位數字就可以了。
輸入輸出樣例
輸入樣例#1:
4 7
輸出樣例#1:
1
說明
用遞迴&遞推會超時
用通項公式也會超時
題解
結論:
然後愉快的矩乘~~
程式碼
#include<bits/stdc++.h>
using namespace std;
const int mod=1e8,N=2;
struct sd{int sq[N+1][N+1];}c,r,one,mat;
int n,m;
int sq[N+1][N+1]={{0,0,0},{0,1,1},{0,1,0}};
sd operator*(sd a,sd b)
{
for(int i=1,j,k;i<=N;++i)for(j=1;j<=N;++j)for(c.sq[i][j]=0,k=1;k<=N;++k)
(c.sq[i][j]+=1ll*a.sq[i][k]*b.sq[k][j]%mod)%=mod;
return c;
}
sd power(sd a,int p){for(r=one;p;p>>=1,a=a*a)if(p&1)r=r*a;return r;}
void in(){scanf("%d%d",&n,&m);}
void ac()
{
for(int i=1;i<=N;++i)one.sq[i][i]=1;
for(int i=1;i<=N;++i)for(int j=1;j<=N;++j)mat.sq[i][j]=sq[i][j];
printf("%d",power(mat,__gcd(n,m)-1).sq[1][1]);
}
int main(){in(),ac();}