CTSC2012の記事[身近]

フェイス質問

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

問題の解決策

#include <cstdioを> 
する#include <CStringの> 
する#include <iostreamの> 
する#include <ベクトル>
 の#define RIレジスタINT
 の#define N 1100050
 の#define INF 998244353
 使用して 名前空間STDを、
ベクトル < 整数 > 息子[N];
INTのN、M、L。
文字列sの、TS;
int型[N]、頭、尾QUE。

構造体SAM {
   int型 FF [N << 1 ]、LEN [N << 1 ]。
  INT CH [N << 1 ] [ 3 ]。
  int型 G [N <<1 ]、F [N << 1 ]。
  int型ラス、TOTを。
  ボイドの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]。
    もし(!p)はFF [NP]は= 1 ;
    {
       INT Q = CH [P]、[C]。
      もし(LEN [P] + 1 == LEN [Q])FF [NP] = Q。
      他の{
        int型 NQ = ++ TOT;
        (RI i = 0 ; iは< 3 ; 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]。
      } 
    } 
  } 
  ブールマッチ(INT L0){
     int型今= 1、CC = 0  = 1 ; ヘッド= 0 ;
    (RI i = 0 ; iが= Lを<; I ++)は[I] = F0、G [I] F [I] = - Iと、
    (RI i = 1 ; iは= Lを<; iは++ ){
       場合(CH [今] [TS [I] - ' 0 ' ]){ 
        CC ++  - CH [今] [TS [I] = ' 0 ' ;]を 
      } 
      {
         ながら(今&& CH [今] [TS [I] - !' 0 ' ])は=のFF [今]。
        もし(!今){  = 1 ; CC = 0 続け; 
        }
        { 
          CC = LEN [今] + 1  - CH [今] [TS [I] = ' 0 ' ;]を 
        } 
      } 
      もし(I> = L0){
         一方(尾<=ヘッド&& G [I-L0]> = G [QUE [頭部]])head-- 
        QUE [ ++ヘッド= I- L0。
      } 
      一方(尾<=ヘッド&& QUE [尾] <I-CC)は尾++ もし(I-CC <= QUE [尾] && QUE [尾] <= I-L0 &&尾<=ヘッド)F [I] = G [QUE [尾] + I。 F [I] = 0 ;
      もし(F [i]が<]; 
      G [I] = F [i]が- 私は、
    } 
    // のprintf( "限界=%d個の\ n"、L0)。
    // のための(RI i = 1; iは= Lを<; iは++){
       // のprintf( "%D%D \ n"は、I、F [I])。
    // }
     // プット( "")。
    (RI i = 1 ; iが<= Lを、iは++)場合((F [I] * 1.0)/(L * 1.0)> = 0.90リターン 1 リターン 0 ; 
  } 
} SAM。

INT メイン(){
   // freopenは( "10.in"、 "R"、STDIN)。
  CIN >> N >> M。2 " ;
   のための(RI i = 1 ; I <= M; iは++)CIN >> TS、S = Sで+ TS + " 2 ; 
  sam.init(); 
  L = s.size();
   のための(RI I = 0 ; iがLに<; I ++)はsam.extend(S [i]は- ' 0 ' );
   のために(RI i = 1 ; iが<= N; iが++ ){ 
    CIN >> TSを、L = ts.size()。
    TS = " " + TS;
     INT LB = 1、RB = L;
     INT ANS = 0 ;
     一方(LB <= RB){
       int型ミッド=(LB + RB)/ 2 もし(sam.match(MID))ANS =中間、LB =ミッド+ 1他の RB =半ば1 
    } 
    COUT << ANS << ENDL。
  } 
}

 

おすすめ

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