行列の初心者

行列は非常に素晴らしいこと、マトリックス+、である - 基本的な操作、*、逆さまなど

その後、我々はそれを行う行列を使用することができますか?

556. Fibonacci数列

(低い時間計算の再帰的問題)

タイトル説明

定義される:F0 = F1 = 1、FN = FN-1 + FN-2(nは> = 2)。{Fiは}フィボナッチ数列と呼ばれます。

入力nは、FNのmod Qを見つけます。ここで、1 <= Q <= 30000。

説明を入力します。

最初の行の数T(1 <= T <= 10000)。Tザ2つの数の行を以下、N、Q(N <= 10 ^ 9、1 <= Q <= 30000)

出力説明

ファイルには、各行が答えに対応し、Tラインが含まれています。

サンプル入力

3
6 2
7 3
7 11

サンプル出力

1
0
10

データ範囲とヒント

1 <= T <= 10000

N <= 10 ^ 9、1 <= Q <= 30000

 

単純にフィボナッチれる分析

しかし、一般的な方法は、O(n)が明らかに十分ではないです、我々は最適化したいです

fが見出さ[N]のみとF、[N-1] F [N-2]の関係を有します

私たちは、複雑な計算無用項目の真ん中を避けることができ、

構造間の関係は、再帰的な追加を可能にする方法行列の乗算を考えるには、乗算の再発となり

【F [1]、F [2]】*【0,1 =【F [2]、F [3]】

                                1、1】

その後、数学的帰納法を見つけることができ、その後すぐに電源

AC:しかし、いくつかの地元の書き込みトラブルのビット

書式#include <cstdioを> 
する#include <CStringの> 
の#include <cstdlib> 
書式#include <アルゴリズム> 
書式#include <CStringの> 
の#include <iostreamの>
 に#define LL長い長い 
 使って 名前空間はstd; 
テンプレート <型名T> 
インラインボイドリード(T&A ){ 
    A = 0ブール B = 0チャー X = GETCHAR()。
    一方、(X < ' 0 ' || ' 9 ' <(x == ' - ')B = 1 
        X = GETCHAR()。
    } 
    一方' 0 ' <= X && X <= ' 9 ' {) =(<< 1)+(<< 3)+ X - ' 0 ' 
        X = GETCHAR()。
    } 
    もし、(B)は、A = - 
} 
チャー C_ [ 50 ]。
int型のTEMP。
テンプレート <型名T> 
インラインボイドライト(T Aの){
    もし(< 0 ){ 
        のputchar(' - ' )。= - ; 
    } 
    行う{ 
        C_ [ ++ TEMP]は%= 10 + 'を0 ' / = 10 
    } 一方、(A)
    一方、(TEMP)のputchar(C_ [TEMP-- ])。
} 
int型、T、Q、N。
構造体平方{
     INT NUM [ 5 ] [ 5 ]、N、M。
    SQ(){ 
        NUM [ 1 ] [ 1] = NUM [ 1 ] [ 2 ] = NUM [ 2 ] [ 1 ] = NUM [ 2 ] [ 2 ] = 0 ; 
    } 
    平方演算子 *(CONST平方&A ){ 
        SQはANS。
        以下のためにint型 I = 1 ; I <= M; I ++ のためのINT J = 1 ; J <= Mであり、j ++ のためのINT K = 1 ; K <= M; ++ k個){ 
            ans.num [I] [ J] =(ans.num [I] [J] + NUM [I] [K] * a.num [K] [J])%のQ。
        } 
        ans.n = ans.m = M。
        戻るANSを。
    } 
    ボイド Get_E(int型N){ 
        N = M = N。
        以下のためにint型 I = 1、N = iは<; iは++)NUMを[I] [I] = 1 
    } 
    ボイドF_init(){ 
        N = M = 2 
        NUM [ 1 ] [ 1 ] = 0 
        NUM [ 1 ] [ 2 ] = NUM [ 2 ] [ 1 ] = NUM [ 2 ] [ 2] = 1 
    } 
}。

インライン平方のquickpow(SQ、int型N){ 
    SQはANS。
    ans.Get_E(2 )。
    
    一方、(N){
         場合(N - 1)ANS = ANS * 
        A * = 
        N >> = 1 
    } 
    戻りANS。
} 
int型のmain(){ 
    (t)を読み出します。
    ながら(t-- ){ 
        (n)を読み出します。
        (Q)を読み込みます。
        SQ; 
        a.F_init(); 
        
        SQ B = quickpow(N) 
        ライト((b.num [ 1 ] [1 ] + b.num [ 2 ] [ 1 ])%のQ)のputchar(' の\ n ' ); 
    } 
    戻り 0 
}

 

 

 

おすすめ

転載: www.cnblogs.com/a-blog-of-taojiayi-2003/p/11237460.html