羅区P1306フィボナッチ条約(数論+証明)

トピックリンク

タイトル効果:__gcd(F [N]、F [M])%の1E8を求めて、あなたにM(1 <= N、M <= 1E9)Nを得ました。

まず第一に、私は数論の定理を提案するためにここにいます:__ GCD(F [N]、F [M])= F [__ GCD(N、M)]。

 

この事実を知って、定理は非常に容易になる数論では、この問題は、単にN、M、及び1E8にモジュロの行列Fを[__ GCD(N、M)]を用いて加速要求の最大公約数を必要とします。

しかし、なぜ定理は正しいでしょうか?


 

動作保証は次の通り:

提供N <M、及びF. [N-] = A、F. [N- + 1] = B

     F [N + 2] = A + B

     F [n + 3] = A + 2 * B = F [N] + 2×F [N + 1]

     F [N + 4] = 2 * + 3 * B = 2 * F [N] + 3 * F [N + 1]

     F [N + 5] = 3 * + 5 * B = 3 * F [N] + 5 * F [N + 1]

     ...

難しい見つけるためにF [N + X] = F [X-1] * F [N] + F [X] * F [N + 1]

     F [M] = F [MN-1] * F [N] + F [MN] * F [N + 1]

所以__gcd(F [N]、 F [M])= __ GCD(F [N]、 F [MN-1] * F [N] + F [MN] * F [N + 1])。

以降  F [MN-1] * F [N]%F [N] == 0

従って __gcd(F. [N-]、F. [M])= __ GCD(F. [N-]、F. [マンガン] F. * [N- + 1])。

 

この式から、単一のは何も表示することは困難である一方で、この式は、単純化して行くことは困難であるため、証明道路はその後、我々は別の補題を必要とする、ここにこだわっているようだ:__ GCD(F [N] 、F [N + 1])= 1。

補題の証明は比較的簡単です:

  __gcd(F [N]、F [N + 1])= __gcd(F [N]、F [N] + F [N-1])

             = __gcd(F [N]、F [N-1])

             = __gcd(F [N-1] + F [N-2]、F [N-1])

             = __gcd(F [N-2]、F [N-1])

             ......

             = __ GCD (F [1]、F [2])= 1

我々は描画__gcd(F [N]、Fが [N + 1])= 1 の後に続けることができる__gcd(F. [N-]、F. [M])= __gcd(F. [N-]、F. [マンガン] *簡略化のためにF [N + 1])

最後__gcd(F. [N-]、F. [M]) = __gcd(F. [N-]、F. [マンガン])

             = __gcd(F [N]、F [Mの%のN])

             ......

             = F [ __gcd(N、M )]

このように、完了の証明〜

 


 

次のコードは、このトピックAC上に置かれています

#include <ビット/ STDC ++ H> 使用して名前空間STDを、
typedefの長い長いLL。
ペアのtypedef < int型int型 > PII。
const int型 MAXN = 1E6 + 10 constのダブル EPS = 1E- 12 ;
constの LL MOD = 1E8; 
LL N、MM。構造体マット{ 
    LL M [ 5 ] [ 5 ]。
    マット(){ 
        memsetの(M、0はsizeof (M))。
    } 
    インラインボイド

 
   

ビルド(){
         ためINT iは= 1 ; I <= 2 ; I ++)M [i]は[I] = 1 
    } 
}。

マットムル(マットは、マットのY、X){ 
    マットC。
    以下のためにINT iは= 1 ; I <= 2 ; I ++ のためのINT J = 1 ; J <= 2、J ++ のためのINT K = 1 ; K <= 2 ; K ++ 
                CM [j]を[I] = (CM [J] [I] + XM [J] [K] * YM [K] [I]%MOD)%のMOD。
    リターンC; 
} 

マットpoww(マットLLのY、X){ 
    マットAA; aa.build()。
    一方、(Y){
         場合(Y&1)AA = ムル(AA、X)。
        X = ムル(X、X)。
        Y >> = 1 
    } 
    戻りAA。
} 

int型のmain()
{ 
    scanf関数(" %LLD%LLD "、&​​N、&MM)。
    LL P = __gcd(N、MM)。
    AM [ 1 ] [ 1 ] = AM [ 2 ] [ 1 ] = AM [ 1 ] [ 2 ] =1 ; 
    マットANS = poww(P- 1 )。
    printf(" %のLLD "、ans.m [ 1 ] [ 1 ])。
}

おすすめ

転載: www.cnblogs.com/Mmasker/p/12059911.html