【CF235C】循環クエスト

フェイス質問

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

問題の解決策

#include <cstdioを> 
する#include <CStringの> 
する#include <iostreamの> 
する#include <ベクトル>
 の#define RIレジスタint型
 の#define N 1000500 使用して名前空間STDを、
ベクター < INT >息子[N << 1 ]。
BOOL VIS [N << 1 ]。
チャーS [N]。
文字列SS。
int型L0; 構造体SAM {
   int型 FF [N << 1 ]、LEN [N << 1 ]。
  INT CH [N << 1 ] [ 26 ]。
  int型

 

CNT [N << 1 ]。
  int型ラス、TOTを。
  INT STK [N << 1 ]、トップ。
  ボイドのinit(){ 
    ラス = TOT = 1 
  } 
  ボイドが伸びる(int型C){
     int型の NP = ++ TOT、P =ラス。ラス= NP。LEN [NP] = LEN [P] + 1 一方(!P && CH [P] [C])CH [P] [C] = NP、Pの=のFF [P]。
    CNT [NP] ++ ;
    もし(!p)はFF [NP]は= 1 ;
    {
       INT Q = CH [P]、[C]。
      もし(LEN [Q] == LEN [P] + 1)FF [NP] = Q。
      他の{
         int型 NQ = ++ TOT;
        (RI i = 0 ; iは< 26 ; I ++)CH [NQ] [I] = CH [Q] [I]; FF [NQ] =のFF [Q]。
        LEN [NQ] = LEN [P] + 1 
        FF [NP] = FFの[Q] = NQ。
        一方(P && CH [P] [C] == Q)CH [P] [C] = NQ、P = FF [P]。
      } 
    } 
  } 
  ボイドmaketree(){
     (RI i = 1 ; I <= TOT; iが++ )息子[FF [I]一back(I)。
  } 
  ボイド treedp(int型X){
     (RI i = 0 ; I <息子[X] .size(); I ++ ){ 
      treedp(息子[X] [I])。
      CNT [X] + = CNT [息子[X] [I]]。
    } 
  } 
  長い 長い(){解決
     長い 長い RET = 0 int型 = CC 0今= 1トップ= 0 ;
    以下のために(RI I = 0、L = ss.size(); iが1- < 1 ; iは++ ){
       int型 C = SSを[I] - [ A ' もし(chは[今] [C]){ 
        CC ++ = [今] [C] CHであり、
        もし(CC> = L0){
           場合(!VIS [今])VIS [今] = 1 [今]、RET + = CNT、STK [++トップ] = 今。
          一方、(!今= 1 && LEN [FF [今]]> = L0- 1)今= FFの[今]。CC = LEN [今]。
        } 
      } 
      {
         ながら(今&& CH [今] [C]!)は=のFF [今]。
        もし(!今){  = 1 ; CC = 0 
        } 
        { 
          CC = LEN [今] + 1 = CHを[今] [C]。
          もし(CC> = L0){
             場合(!VIS [今])VIS [今] = 1 [今]、RET + = CNT、STK [++トップ] = 今。
            一方、(!今= 1 && LEN [FF [今]]> = L0- 1)今= FFの[今]。CC = LEN [今]。
          } 
        } 
      } 
    } 
    のための(RI I =頂; I> = 1 ; i--)VIS [STKの[I] = 0 ; VIS [ 1 ] = 0 リターンRET; 
  } 
} SAM。

INTのN、M。
INT STK [N << 4]、上;
INT メイン(){ 
  sam.init()。
  scanf関数(" %sの" 、S);
  (RI I = 0 sam.extend(S [I] - ; iがLに<I ++は、L個の=のSTRLEN(S))' A ' ); 
  sam.maketree(); 
  sam.treedp(1 )。
  scanf関数(" %のD "、&N)
  (RI i = 1 ; iが<= N; iは++ ){ 
    CIN >> SSと、L0 = ss.size()。
    SS = SS + SS。
    COUT << sam.solve()<< ENDL。
  } 
}

 

おすすめ

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