フェイス質問
http://darkbzoj.tk/problem/3277
問題の解決策
#include <cstdioを> する#include <iostreamの> する#include <CStringの> する#include <ベクトル> の#include < 設定 > の#define N 100050 の#define intを登録RI 使用して 名前空間STDを、 int型N、K。 構造体ノード{ int型FF、LEN。 INT [CH 26 ]。 設定 < 整数 > 秒; } T [N << 1 ]。 ベクター < INT >息子[N << 1 ]。 構造体SAM { int型CNT [N << 1 ]。 int型最後、TOT; 無効のinit(){ 最後 = TOT = 1 。 } INT(延びINT P、INT C、INT ID){ int型のNPを、 { NP = ++ TOT。 T [NP] .LEN = T [P] + .LEN 1 。 一方、(!P && T [P] [C] .CH)T [P]は[C] = NP、P = .CH T [P] .ffと、 もし(!{P) T [NP] .ff = 1 。 } 他{ INTQ = T [P] .CH [C]。 もし(T [Q] .LEN == T [P] .LEN + 1 ){ T [NP] .ff = Q。 } 他{ INT NQ = ++ TOT。 T [NQ] = tの[Q]。tは[NQ] .LEN = T [P] + .LEN 1 。 T [NP] .ff = T [Q] .ff = NQ。 一方、(Pの&& tの[P] .CH [C] == Q)T [P] .CH [C] = NQ、P = T [P] .ff。 } } } T [NP] .s.insert(ID)。 リターンNP。 } ボイドmaketree(){ 用(RI i = 1 ; I <= TOT; I ++)息子[T [i]は.ff] .push_back(I)。 } ボイドマージ(INT X){ ため(RI I = 0、L =息子[X] .size(); iがLに<; Iは++ ){ (息子[X] [i])と合流します。 設定 < 整数 > ::イテレータit。 以下のための T [X](。;;それ= T [息子[X] [I]] s.end()!。++、それそれがT [息子[X]を[I]] s.begin()=)。 s.insert(* これ)。 } } } SAM。 ストリングS [N]。 int型のmain(){ IOS :: sync_with_stdio(偽); CIN >> N >> K。 sam.init(); 用(RI i = 1 ; iが<= N; I ++){ CIN >> S [i]は、 int型のp = 1 ; 用(RI jが= 0、L = Sで[I] .size(); J <Lであり、j ++)P = sam.extend(P、S [i]は[J] - ' A ' 、I)。 } sam.maketree()。 sam.merge(1 )。 用(RI i = 1 ; iが<= N iが++ ){ int型の CNT = 0。長い 長い ANS = 0 ; int型になりました= 1 ; 用(RI J = 0、L = Sで[I] .size(); J <Lであり、j ++ ){ もし(T [T [今] .CH [S [i]は[J] - ' ' ] s.size()> = K){ CNT ++ 。 今 Tを= [今] .CH [S [i]は[J] - ' ' ]。 ANS + = CNT; } 他{ ながら(今&& T [T [今] .CH [S [i]は[J] - ' ' ] s.size()<K。)今= T [今] .ff。 もし(!今){ CNT = 0 ; 今= 1 ; } 他{ CNT [今] =さt + .LEN 1 。 今 Tを= [今] .CH [S [i]は[J] - ' ' ]。 ANS + = CNT; } } } COUT << ANS << " " 。 } 戻り0 。 }