羅区[P3804]サフィックスオートマトン

フェイス質問

https://www.luogu.org/problem/P3804

問題の解決策

// luogu-判定部は、有効-O2 
の#include <cstdioを> 
する#include <iostreamの> 
の#include <CStringの>
 に#define里登録int型
 の#define N 1000050
 使用して 名前空間はstd; 

チャーS [N]。
int型のn;
int型 ANS = 0 ; 

構造体SAM {
   int型 FF [N << 1 ]、CNT [N << 1 ]。
  INT CH [N << 1 ] [ 26 ]。
  INT LEN [N << 1 ]。
  int型のTOT、最後。
    
  int型のトン[N << 1]、[N << 1 ]。

  インラインボイドコピー(INT NQ、INT Q){
     ため(RI i = 0 ; iが< 26 ; iが++)CH [NQ] [I] = CH [Q] [I]; 
    FF [NQ] =のFF [Q]。
  } 
  インラインボイド(伸びるINT O){
     int型、P = 最後に、NP、Q、NQと、
    NP = ++ TOT; 
    LEN [NP] = LEN [P] + 1 
    最後 = NP。
    一方(!P && CH [P] [O])CH [P] [O] = NP、Pの=のFF [P]。
    もし(!p)はFF [NP] =1 ;
    そうでなければ{ 
      Q = CH [P] [O]。
      もし(LEN [Q] == lenの[P] + 1)FF [NP] = Q。
      他の{ 
        NQ = ++ TOT; 
        コピー(NQ、Q); 
        LEN [NQ] = LEN [P] + 1 
        FF [NP] = FFの[Q] = NQ。
        一方(P && CH [P] [O] == Q)CH [P] [O] = NQ、P = FF [P]。
      } 
    } 
    CNT [NP] = 1 
  } 

  ボイドワーク(){
     (RI i = 1 ; I <= TOT; iは++)トン[LEN [I]] ++;
    (RI I = 1トン[I] + =トン[1-; iが<= N I ++)は1 ]。
    (RI i = 1 ; I <= TOT; iが++)[トンLEN [I]] - ] = I。
    (RI iはTOTを=; I> = 1 ; i--)CNT [FF [I]]] + = CNT [i]が]。
    (RI i = 1 ; I <= TOT; iは++)場合(CNT [I]> 1)ANS = MAX(ANS、LEN [I] * CNT [I])。
  } 
} SAM。

INT メイン(){ 
  scanf関数(" %sの"、S + 1 )。
  N = STRLEN(S + 1 )。
  sam.tot = 1; sam.last = 1 (RI I = 1 sam.extend(S [I] - ; iが<= N I ++)は' A ' ); 
  ANS = 0 ; 
  sam.work(); 
  printf(" %d個の\ n " 、ANS)。
}

 

おすすめ

転載: www.cnblogs.com/shxnb666/p/11278663.html