ZROI # 1119

ZROI # 1119

It looks very weird ... because before know \ (Fibonacii \) number of items listed on the formula, so we always thought that this problem is \ (F \) recursive transfer through entry ...

I never thought this turned out to be accelerated matrix recurrence ...

\ (⑧ \) said, sadly, directly on the formula:

\[\begin{aligned} F_{n} &=\sum_{i=0}^{n} f_{i} f_{n-i} \\ &=\sum_{i=0}^{n}\left(f_{i-1}+f_{i-2}\right) f_{n-i}+f_{1} f_{n-1}+f_{0} f_{n} \\ &=\sum_{i=0}^{n-1} f_{i} f_{n-i-1}-f_{0} f_{n-1}+\sum_{i=0}^{n-2} f_{i} f_{n-i-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} \end{aligned}\]

So we have a recurrence formula, we find that this is a recursive formula and \ (F \) and \ (f \) adjacent to two related, so our original matrix and the target matrix should be kept for at least four-dimensional state.

And because the answer required is \ (F \) prefix and so should be more one-dimensional to assist recurrence, so we should be the transition matrix \ (5 \ times 5 \) it is.

We found the original matrix and the target matrix should be this sub-sub-:

\[\left[\begin{array}{lllll}{?} & {?} & {?} & {?} & {?} \\ {?} & {?} & {?} & {?} & {?} \\ {?} & {?} & {?} & {?} & {?} \\ {?} & {?} & {?} & {?} & {?} \\ {?} & {?} & {?} & {?} & {?}\end{array}\right]\left[\begin{array}{c}{F_{i}} \\ {F_{i-1}} \\ {f_{i}} \\ {f_{i-1}} \\ {a n s_{i}}\end{array}\right]=\left[\begin{array}{c}{F_{i+1}} \\ {F_{i}} \\ {f_{i+1}} \\ {f_{i}} \\ {a n s_{i+1}}\end{array}\right]\]

Matrix is ​​a question mark we have to derive the transfer matrix.

After derivation, can be obtained transfer matrix is ​​such that:

\[\left[\begin{array}{lllll}{1} & {1} & {0} & {0} & {1} \\ {1} & {0} & {0} & {0} & {1} \\ {1} & {0} & {1} & {1} & {1} \\ {1} & {0} & {1} & {0} & {1} \\ {0} & {0} & {0} & {0} & {1}\end{array}\right]\left[\begin{array}{c}{F_{i}} \\ {F_{i-1}} \\ {f_{i}} \\ {f_{i-1}} \\ {a n s_{i}}\end{array}\right]=\left[\begin{array}{c}{F_{i+1}} \\ {F_{i}} \\ {f_{i+1}} \\ {f_{i}} \\ {a n s_{i+1}}\end{array}\right]\]

As for how to derive, I will have a blog devoted to how to derive a matrix, are not repeated here.

Happy on the ground directly to a fast power matrix.

The initial matrix is \ (1 \ times 5 \) a \ (: \ {2,1,1,1,3 \} \)

Note that, because the initial matrix is from the beginning of the first term, every time the transfer matrix multiplication backward recurrence time, so the number of transfer what we need is \ (n-1 \) is.

Happy \ (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 ;
}

Guess you like

Origin www.cnblogs.com/Equinox-Flower/p/11672211.html