1. 程式人生 > >洛谷P1306 斐波那契公約數

洛谷P1306 斐波那契公約數

正整數 toolbar ostream scan 應該 -c acc 整數 之前

P1306 斐波那契公約數

題目描述

對於Fibonacci數列:1,1,2,3,5,8,13......大家應該很熟悉吧~~~但是現在有一個很“簡單”問題:第n項和第m項的最大公約數是多少?

輸入輸出格式

輸入格式:

兩個正整數n和m。(n,m<=10^9)

註意:數據很大

輸出格式:

Fn和Fm的最大公約數。

由於看了大數字就頭暈,所以只要輸出最後的8位數字就可以了。

輸入輸出樣例

輸入樣例#1:
4 7
輸出樣例#1:
1

說明

用遞歸&遞推會超時

用通項公式也會超時

/*
    首先,斐波那契數列相鄰項的gcd=1。假設不為1的話,可以推出之前所有相鄰項gcd均不為1,但gcd(f(1),f(2))=gcd(1,1)=1,矛盾,所以相鄰項gcd=1。
    然後,不妨設n<m,設第f(n)與f(n+1)為a,b,則有:
    x f(x)
    0 0 1 1 2 1 3 2 ... (n)a,(n+1)b
    (n+2)a+b
    (n+3)a+2b
    (n+4)2a+3b
    ...
    (m)f(m-n-1)a+f(m-n)b
    根據gcd(m,n)=gcd(n,m%n),則
    gcd(f(m),f(n))
    =gcd(f(n),f(m)%f(n))
    =gcd(a,f(m-n)b)
    因為a和b是相鄰項,gcd=1,所以
    _原式_=gcd(f(n),f(m-n))
    遞歸帶入,得到
    _原式_=gcd(f(n),f(m%n))
    這就是gcd輾轉相除的形式,所以可以得到
    gcd(f(m),f(n))=f(gcd(m,n))
    問題解決
    只需要先用O(logn)時間求gcd(m,n),再求f(gcd(m,n))
*/ #include<iostream> #include<cstdio> using namespace std; long long n,m,a[1000000]; int gcd(int x,int y){ if(y==0)return x; else return gcd(y,x%y); } int main(){ scanf("%d%d",&n,&m); int p=gcd(n,m); a[1]=1;a[2]=1; for(int i=3;i<=p;i++)a[i]=(a[i-1
]+a[i-2])%100000000; printf("%d",a[p]); return 0; }

洛谷P1306 斐波那契公約數