フェイス質問
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。 } }