ZROIの#1119

ZROIの#1119

前に知っているので、それは...非常に奇妙に見える\(Fibonacii \)式に記載されているアイテムの数を、私たちは常にこの問題があると思った\(F \)エントリー全体に再帰的転送...

私は、これは、マトリックスの再発を加速することが判明思ったことはありません...

\(⑧\)直接式で、悲しいことに、言いました:

\ [\(開始{整列} F_ {N}&= \ sum_ {i = 0} ^ {n}はF_ {I} F_ {NI} \\&= \ sum_ {i = 0} ^ {N} \左F_ {I-1} + F_ {I-2} \右)F_ {NI} + F_ {1} F_ {N-1} + F_ {0} F_ {N} \\&= \ sum_ {i = 0 } ^ {N-1} F_ {I} F_ {NI-1} -f_ {0} F_ {N-1} + \ sum_ {i = 0} ^ {N-2} F_ {I} F_ {NI- 2} + F_ {1} F_ {N-1} + F_ {0} F_ {N} \\&= F_ {N-1} + F_ {N-2} + F_ {1} F_ {N-1} -f_ {0} F_ {N-1} + F_ {0} F_ {N} \\&= F_ {N-1} + F_ {N-2} + F_ {N} \端{整列} \]

だから我々は、我々は、これは再帰的な式であることがわかり、漸化式があり、\(F \)\(のF \)二つの関連に隣接したが、その独自のマトリックスとターゲットマトリックスは、少なくとも4つの次元の状態のために維持されなければなりません。

必要な答えがあるためと\(F \)プレフィックスとその再発を支援するために、より一次元でなければなりませんので、我々は、遷移行列でなければなりません\(5 \回5 \)それがあります。

私たちは、元の行列を発見し、ターゲット・マトリックスは、このサブサブする必要があります:

\ [\ [\ {アレイ} {LLLLLを}開始{?}&{?}&{?}&{?}&{?} \\ {?}&{?}&{?}・{}?&左{?} \\ {?}&{?}&{?}&{?}&{?} \\ {?}&{?}&{?}&{?}&{?} \\ {}? &{?}&{?}&{?}&{?} \端{アレイ} \右] \左[\開始{アレイ} {C} {F_ {I}} \\ {F_ {I-1} } \\ {F_ {I}} \\ {F_ {I-1}} \\ {S_ {I}} \端{アレイ} \右] = \左[\開始{アレイ} {C} {F_ {I + 1}} \\ {F_ {I}} \\ {F_ {I + 1}} \\ {F_ {I}} \\ {S_ {I + 1}} \端{アレイ}右\ ] \]

行列は、我々は、転送行列を導出する必要が疑問符です。

導出した後、得られる伝達行列はようなものです。

\ [\ [\ {1} {アレイ} {LLLLLを}開始&{1}と{0}&{0}と{1} \\ {1}と{0}&{0}&{0}&左{1} \\ {1}と{0}と{1}と{1}と{1} \\ {1}と{0}と{1}と{0}と{1} \\ {0} &{0}&{0}&{0}と{1} \端{アレイ} \右] \左[\開始{アレイ} {C} {F_ {I}} \\ {F_ {I-1} } \\ {F_ {I}} \\ {F_ {I-1}} \\ {S_ {I}} \端{アレイ} \右] = \左[\開始{アレイ} {C} {F_ {I + 1}} \\ {F_ {I}} \\ {F_ {I + 1}} \\ {F_ {I}} \\ {S_ {I + 1}} \端{アレイ}右\ ] \]

導出する方法については、私は行列を導出する方法に専念ブログは、ここでは繰り返さないがあります。

高速電力行列への直接地面にハッピー。

初期行列である\(1 \回5 \)\(:\ {2,1,1,1,3 \} \)

初期行列は、第一項の最初から転送行列乗算後方再発時間ごとの時間ですので、我々は必要なもの転送の数がされているので、それに注意してください(N-1 \)\です。

ハッピー\(AC!\)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#define MEM(x,y) memset ( x , y , sizeof ( x ) )
#define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
#define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
#define pii pair < int , int >
#define one first
#define two second
#define rint read<int>
#define rll read<LL>
#define LL long long
#define pb push_back
#define db double
#define mid ( ( l + r ) >> 1 )

using std::queue ;
using std::set ;
using std::pair ;
using std::max ;
using std::min ;
using std::priority_queue ;
using std::vector ;
using std::swap ;
using std::sort ;
using std::unique ;
using std::greater ;

template < class T >
    inline T read () {
        T x = 0 , f = 1 ; char ch = getchar () ;
        while ( ch < '0' || ch > '9' ) {
            if ( ch == '-' ) f = - 1 ;
            ch = getchar () ;
        }
        while ( ch >= '0' && ch <= '9' ) {
            x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
            ch = getchar () ;
        }
        return f * x ;
    }

const int mod = 998244353 ;

struct Matrix {
    LL e[5][5] , line , row ;

    inline void clear () { line = row = 0 ; MEM ( e , 0 ) ; return ; }

    friend Matrix operator * (Matrix a , Matrix b) {
        Matrix c ; c.clear () ; c.line = a.line ; c.row = b.row ;
        rep ( k , 0 , a.row - 1 ) rep ( i , 0 , a.line - 1 ) rep ( j , 0 , b.row - 1 )
            c.e[i][j] = ( c.e[i][j] + a.e[i][k] * b.e[k][j] % mod ) % mod ;
        return c ;
    }
} ;

inline Matrix quick (Matrix a , LL p) {
    Matrix c ; c.clear () ; c.line = a.line ; c.row = a.row ;
    rep ( i , 0 , c.line - 1 ) c.e[i][i] = 1 ;
    while ( p ) {
        if ( p & 1 ) c = c * a ;
        a = a * a ; p >>= 1 ;
    }
    return c ;
}

LL n , k ; Matrix p ;

int main(){
    n = rll () ; p.clear () ;
    p.e[0][0] = p.e[1][0] = p.e[2][0] = 1 ;
    p.e[3][0] = p.e[0][1] = p.e[2][2] = 1 ;
    p.e[3][2] = p.e[0][4] = p.e[1][4] = 1 ;
    p.e[2][4] = p.e[3][4] = p.e[4][4] = 1 ;
    p.e[2][3] = 1 ; p.line = 5 ; p.row = 5 ;
    Matrix ans = quick ( p , n - 1ll ) ; ;
    Matrix pri ; pri.clear () ;
    pri.line = 1 ; pri.row = 5 ;
    pri.e[0][0] = 2 ; pri.e[0][1] = 1 ;
    pri.e[0][2] = 1 ; pri.e[0][3] = 1 ;
    pri.e[0][4] = 3 ; ans = pri * ans ;
    printf ("%lld\n" , ans.e[0][4] ) ;
    system ("pause") ; return 0 ;
}

おすすめ

転載: www.cnblogs.com/Equinox-Flower/p/11672211.html