行列は非常に素晴らしいこと、マトリックス+、である - 基本的な操作、*、逆さまなど
その後、我々はそれを行う行列を使用することができますか?
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 。 }