[Bzoj4516]呪文を生成します

サフィックスオートマトンを確立し、各状態総LEN [k]が-len [FA [K ] です。

1つの#include <ビット/ STDC ++ H>
 2  使用して 名前空間STDを、
3  の#define N 100005
 4  の#define CALC(K)(LEN [K] -len [FA [K])
 5地図< INTINT > CH [N << 1 ]。
6  int型 V、最後に、N、K、LEN [N << 1 ]、合計[N << 1 ]、FA [N << 1 ]。
7つの 長い 長いANS;
8  ボイド追加(INT C){
 9      のint p =最後に、NP =最後= ++ V。
10      LEN [NP]はLEN [P] + = 1;
11      のために((P)&&(CH [P] [C]);!p = FA [P])CH [P]は[C] = Vします。
12      であれば(!のP){
 13          、FA [NP] = 1 14の          ANS + = CALC(NP)。
15      }
 16      {
 17          INT Q = CH [P]、[C]。
18          であれば(LEN [Q] == LEN [P] + 1 ){
 19              、FA [NP] = Q。
20の              ANS + = CALC(NP)。
21          }
 22          {
 23              INT NQ = ++ V。
24             LEN [NQ] = LEN [P] + 1 25個の              CH [NQ = CH [Q]。
26              FA [NQ = FA [Q]。
27の              ANS + = CALC(NQ) - 計算値(Q)。
28の              FA [NP] = FA [Q] = NQ。
29の              ANS + = CALC(NP)+ 計算値(Q)。
30              のために((P)&&(CH [P] [C] == Q); P = FA [P])CH [P]、[C] = NQ。
31          }
 32      }
 33  }
 34  INT メイン(){
 35      V =最後= 1 36      のscanf(" %d個"、&N);
37      のためには、int型 i = 1 ; iが<= N; iが++ ){
 38          のscanf(" %dの"、&K)。
39          追加(K)。
40          のprintf(" %LLDする\ n " 、ANS)。
41      }
 42 }
コードの表示

 

おすすめ

転載: www.cnblogs.com/PYWBKTDA/p/11249943.html