FZU2018レベルアルゴリズム最初のジョブ1.1fibonacci(マトリックス高速電力)

タイトル

  フィボナッチ数列の学習にワインダー最近の知識。我々は、列の数は、再帰式をF(N)= F(nはフィボナッチことを知っている -1)+ F(N-2)(N> = 2 、nは整数です)。この再帰F(N)へ=ときに我々が知りたいワインダーであるF(1-N)B + F(N-2)(N> = 2、nは整数である)、我々が何を得ます列の数。これを成し遂げるために彼を助けるためにこれだけあなたまで、しかし、ワインダーは怠惰。なお、ここで我々はまだFを作ること(0)= F(1 )= 1。

★データ入力

  最初の行の入力3つの正の整数N、A、及びB(N <= 10; 1 <= A、B <= 100、整数です)。次いで、N行、各行の自然数N(N <= 100000000)があります。

★データ出力

  結果としてライン出力整数F(n)は、大きくてもよい、ワインダーはモジュロ2013の出力を必要としました。

入力例 出力例

5 4 5

2

4

8

16

32

9

209

1377

182

9

 

ソリューション:

  古典行列は、迅速な電源の問題を産みました。

  我々は$ A ^ {B}時のMODモジュラスを$を要求すると、まず、高速のパワーを説明するために、bはバイナリ、Bに変換することができる和の2乗の数に変換することができます。我々は2の12乗を計算する際に、例えば、12は、それぞれ2つの4 1と8、1100、1100の二進ビット重みであるので、^ {12} $回$ 2を容易に$ 2 ^ {4}に変換することができます。 * $ 2 ^ {8}。したがって、我々は最初の回答ANS 1,2,4,8 ..... 1つのパワー、計算のみに割り当てられ、その後、1を場合、1をすることができ、ビットbの値を見て、ANS缶を掛けました。

高速電源コードを次のように

LLのfastpow(LLのB、LL)
{ 
    LL ANS = 1 一方、(b)は、
    { 
        もし、(B&1)ANS = ANS *%のMOD。= A *%のMOD。
        B >> = 1 
    } 
    戻りANS。
}

  次に、より大きな数nは、剰余プラス遅く、この質問再帰再帰タイムアウトするので、この問題に戻ります。我々は、アルゴリズムの複雑さはO(n)がA未満である見つける必要があります。

  我々は、マトリックスの$ \のbinom {F(N)} {F(N-1)} $を構築することができ得ることができます

$$
\左(
\開始{行列}
A&B \\
1&0
\端{行列}
\右)\タグ{2} ^ {N-1} *
\ binom {F(1)} {F(0 )} = \ binom {F(N)} {F(N-1)}
$$

したがって、我々は唯一の行列を計算する必要があります

$$
\左(
\ {行列}始める
A&B \\
1&0
\端{行列}
\右)
$$

N-1番目の電力は、この行列のn-1乗、高速シークマトリックスを使用することによって得られた電力のため、我々は$ \ログのn $時間のF(n)の値を算出することができることができます。

書式#include <iostreamの> 
の#include
<cstdioを> する#include <アルゴリズム> 書式#include <cmath> の#include <cstdlib> 書式#include <CStringの> の#include < 文字列 > の#include <ベクトル> の#include <キュー> の#include < 設定 > 使用して 名前空間はstdを、 typedefの長い 長いLL。 typedefの長い ダブルLD; typedefの符号なしの長い 長いULL。 typedefのペア < int型PII; #define担当者(I、x、y)がため(I = xをint型、I yを<; I ++) の#define REPT(I、x、y)がため(I = xをint型、iは= yと<; iは++) の#define当たり(I、x、y)は(I = int型のX; I> = Y; i--)のため の#define PB一back の#define Fiの第一 の#define SE第二 の#define MES(B)のmemset(A、B、はsizeof A) のconst int型 INF = 0x3f3f3f3f const int型のmod = 2013 ; クラス行列 { パブリックINT arrcy [ 6 ] [ 6 ]; // arrcy为矩阵、表从0开始下 INT行、列; //行为矩阵的行、列为矩阵的列 友人行列演算子 * (行列S1、マトリックスS2) { int型私は、jは、 行列S3; (i = 0 ; iは<s1.row iは++ { ため(J = 0 ; J <s2.column; J ++ { ためint型のk = 0 ; K <s1.columnあり、k ++ { s3.arrcy [ I] [J] + = s1.arrcy [I] [K] * s2.arrcy [K] [J]。 s3.arrcy [I]、[J](%)= MOD。 } } } S3.row = s1.row; s3.column = s2.column; 戻りS3を; } }; マトリックスquick_pow(マトリックスS1、ロング ロングN-)//高速電力関数行列、S1行列、n個の電源であります { 行列MUL = S1、ANS;
// ANSをマトリックスとして構成することが ans.row
= ans.column = s1.row; のmemset(ans.arrcy、0はsizeofのans.arrcy); のためint型 I = 0を I。 <ans.row; I ++ ans.arrcy [i]は[I] = 1 一方、(N) { 場合(N - 1)ANS = ANS * MUL。 MUL = MUL * MUL。 N / = 2 } 戻りANS。 } int型のmain() { IOS :: sync_with_stdio()。 cin.tie(0 )。 int型N、B。 CIN >> N >> A >> B。 行列MUL。 mul.row = mul.column = 2 mul.arrcy [ 0 ] [ 0 ] = mul.arrcy [ 0 ] [ 1 ] = B; mul.arrcy [ 1 ] [ 0 ] = 1 mul.arrcy [ 1 ] [ 1 ] = 0 行列R。 r.row = 2 r.column = 1 r.arrcy [ 0 ] [ 0 ] = r.arrcy [ 1 ] [ 0 ] = 1 担当者(I、0 、N) { int型のX; cinを >> X; もし(!X)//場合、X = 1、<-1× 0が高速電力を使用できない、答えは0であり、文献判定缶 { COUT << 1。 << ENDLと、 続行; } マトリックスMM = quick_pow(MUL 、X- 1 ); MM = MM * R&LT; COUT << mm.arrcy [ 0 ] [ 0 ] << ENDL; } 戻り 0 ; }

 

おすすめ

転載: www.cnblogs.com/FZUzyz/p/11490946.html