CF1106F旧正月と再帰Sequence--行列高速電力&& BSGS

問題の意味

设$$のf_i = \左\ {\開始{行列}
1、\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ I <K \\
\ prod_ {J = 1} ^ k個のF_ {IJ} ^ {b_j} MODの\ P \ \ \ \ \ \ I> K
\端{行列}右\。$$

要求の$ F_Kの$($ 1 \当量F_K <Pの$)は、$ F_M = n個の$ように。($ 1 \当量のK \当量100 $)

分析

$ $ F_nは$ {F_K} ^ Xの$、すなわち線形再帰的指数、高速電力周波数とF_n $ $ラインで得られた最終的な行列の形で表すことができます。

$$ \開始{bmatrix} F_K \\ F_ {K-1} \\ \ vdots \\ F_1 \端{bmatrix} =
\ {bmatrix} B_1とB_2&\ cdots&b_k \\ 1&0&0&始まります0 \\ \ vdots&\ ddots&\ vdots&\ vdots \\ 0 0 1 0&\端{bmatrix} \ CDOT
\開始{bmatrix} F_ {K-1} \\ F_ {K-2} \ \ \ vdots \\ F_0 \端{bmatrix} $$

即$ F_n = Bの\のCDOT F_ {N-1} = B ^ {NK} F_K $

それは$ {F_K} ^ X \当f_n \(MOD P)$ X $は既に高速電力行列をカウントした形態を$です。

その後、フォームは、x ^ \当量のBの\ PMOD {P} $方程式、直接テンプレートを$を解くことについてです。

その元のルートは、3 998 244 353であり、右、常識と考え

、金型は、$ P $のないときに、電力事業者の行列迅速、オイラーの定理により、金型は、$ P-1 $であることに注意してください。

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、

typedefの長い 長いLL。
構造体行列
{ 
    int型のR、C。
    LLマット[ 101 ] [ 101 ]。
    行列(){ 
        memsetの(マット、0はsizeof (マット))。
    } 
}。
constの LLのP = 998244353 ;
int型 K、B [ 110 ]、N、M。

マトリックスMUL(行列A、行列B、LLのP)    // 矩阵相乘
{ 
    マトリックスRET。
    ret.r =アルゴン。ret.c = Bcを。
    以下のためにint型 i = 0 ; iは、ARと<; I ++ のためのINT K = 0 ; K <のAcあり、k ++ のためのint型 J = 0 ; J <Bcを、J ++ 
            { 
                ret.mat [I] [J] = (ret.mat [I] [J] + A.mat [I] [K] * B.mat [K] [J])%のP。
            } 
    戻りRET。
} 

マトリックスmpow(行列A、INT nは、INTのP)
{ 
    マトリックスRET。
    ret.r =アルゴン。ret.c = のAc。
    以下のためのINT I = 0 ; I <ret.r; iは++)ret.mat [i]は[I] = 1 一方、(N)
    { 
        場合(N - 1)RET = MUL(RET、A、P)。
        A = MUL(A、A、P)。
        N >> = 1 
    } 
    戻りRET。
} 

LLのGCD(LLのB、LL)
{ 
    戻り B?GCD(B、%のB)。
} 

LL qpow(LLのB、LLのP LL)
{ =%のP。
    LL RET = 1 一方、(B)
    { 
        もし(B&1)RET = RET *%のP。= A *%のP; 
        B >> = 1 
    } 
    戻りのRET%のP。
} 



マップ < INTINT > 融点;
int型(BSGS のintint型 B、int型 P){     // A ^ X = B(MOD P)、(P)は1、返回X、X> = 1 = 
    INT M = SQRT(P)+ 1 。 mp.clear();
    ため(登録をint i = 0 ; iがmを<;、RES = bを++ I、RES = 1LL * RES *%のP)MP [RES] = I。
    にとって(登録INT I = 1 RES = TMP、TMP = qpow(M、P); I <= M + 1 ; ++ I、RES = 1LL *解像度* TMP%のP)の
         場合(mp.count(RES) )リターン私はM- * MPを[RES]。
    戻る - 1 
} 

int型  のmain()
{ 
    scanf関数(" %のD "、&K)。
    int型 iは= 1のscanf(;私は= Kを<I ++)は、 " %のD "、&B [I])。
    scanf関数(" %d個の%のD "、&​​N、&M)。
    行列B。
    BRの = Bcを=K;
    以下のためにint型私= 0 ; I <K; iは++)B.mat [ 0 ] [I] = bの[I + 1 ]。
    以下のためにint型 i = 1 ; iはkは<; iは++)B.mat [I] [I- 1 ] = 1 

    B = mpow(B、NK、P- 1 )。     
    INT A = B.mat [ 0 ] [ 0 ]%(P- 1)。    // 注意、是模P-1而非P 

    INT C = BSGS(qpow(3 、P)、M、P)。
    もし - (C == 1のprintf()" -1 \ nを");
    
    { 
        INT FK = qpow(3 、C、P)。
        printf(" %d個の\ n " 、FK)。
    } 
}

 

 

参考リンク:https://www.cnblogs.com/bztMinamoto/p/10348641.html

 

おすすめ

転載: www.cnblogs.com/lfri/p/11511210.html