羅区P2414 / LOJ2444 / BZOJ2434 [NOI2011]アリのタイプライター

AC自動機は1975年に発明されたので、これは古代のタイプライターの技術とみなすことができるので、

まず、それに沿ってすべてスキップして、文字列に対応するノードのトライサフィックス代表の現在のノードにジャンプすることで、ポインタが考案されて失敗するので、私たちが知ることができるACオートマトンの性質を調べ、我々だけで内部の統計yをどのように多くのノードがそれで失敗エンドXジャンプをスキップすることができます。

しかし、この事は確かに暴力をジャンプすることはできません。我々はyのノードがツリーに染めている置けば、ノーそして、側面を参照してください木(ツリーが失敗)の転移形成に失敗することが困難になるために失敗し、その答えは、そのサブツリーは、いくつかの結び目を持っているXはポイントを染めている、これは+フェンウィックツリーDFSを命ずることができます。

そこで問題は、どのくらいの速染色yにすべてのノードがあります。リカバリ中に各ポイントを出るときだけY yの終わりに実行したときトライでDFSを実行して、オフラインで考える、染色は、すべてのノードが染色されます。ここではそこのyに関するすべてのお問い合わせに先立って、均一な処理をすることができます。

書式#include <cstdioを> 
する#include <CCTYPE> 
書式#include <CStringの> 
の#include <ベクトル> 
の#include <キュー>
 使用して 名前空間はstd;
const  int型 N = 100050 ;
INT F [N]、CH [N] [ 26 ]、CH 2 [N] [ 26 ]、CNT = 0、POS [N]、失敗[N]、ANS [N]、DFN [N]、DFL [N] 、dfsc = 0、[N] C、G [N]、[N]に、NXT [N]、SZ = 0 チャーS [N]。
ベクター < INT > QRY [N]、QP [N]。
キュー < 整数 > Q; 
インライン無効BFS(){
     int型Uは、Iと、
    (i = 0 ; iは< 26 ; ++ I)もし(CH [ 0 ] [i])とQ.push(CH [ 0 ] [I])。
    一方、(!{Q.empty())
        U = Q.front(); Q.pop()。
        (i = 0 ; iは< 26 ; ++ I)の場合(CH [U]は[I]){ 
            失敗[CH [U] [I] =のCH [I] [U]は[失敗]。
            Q.push(CH [U] [I])。
        }  CH [U] [I] =のCH [失敗[U]]は[I]。
    } 
} 
インラインボイド ADDE(INT U、INT V){ 
    [に対して SZ ++] = V; NXT [SZ] = G [U]、G [U] = SZ。
} 
インラインボイド追加(int型のx、短いK){
     ため(; X <= CNT + 1、X + = X&-x)C [X] + = K。
} 
インラインint型の和(INT X){
     int型、S = 0 (; X; X ^ = X&-x)S + = C [X]。
    リターン秒; 
} 
ボイド DFS1(INT U){ 
    DFN [U]は = ++ dfsc。
    以下のためのint型I = G [U]; I; I = NXT [i])とDFS1([i])とします。
    DFL [U] = dfsc。
} 
ボイド DFS2(int型Uを){
     int型のI。
    追加([U] DFN、1 )。
    (i = 0 ; I <QRY [U]は.size(); ++ I)ANS [QP [U] [I] = SUM(DFL [QRY [U] [i]は]) -和(DFNの[ QRY [U] [I]] - 1 )。
    (i = 0 ; iは< 26 ; ++ I)もし(CH 2 [U] [i])とDFS2(CH 2 [U] [I])。
    追加(DFN [U]、 - 1 )。
} 
int型のmain(){
     int型 Q、I、X、Y、L、N = 0、K = 0 
    のscanf(" %sの"、S);リットル=のSTRLEN(S)
    (i = 0 ; iはL <; ++ I)であれば(islowerは(S [I])){
         場合(CH [K] [S [i]が! - ' A ' ])CH [K] [S [ I] - ' ' ] = ++ CNT; 
        F [CH [K] [S [I] - ' ' ] = K; K = CH [K] [S [I] - ' ' ]。
    } そうであれば(S [I] == ' B ')は、k = F [k]は、
     POS [++ N] = K。
    memcpy(CH 2、CH、はsizeof (CH2))。
    BFS(); 
    (i = 1 ; iは= CNT <; ++ I)ADDE([i]が失敗し、i)を、
    DFS1(0 )。
    scanf関数(" %のD "、&Q)。
    (i = 0 ; iはQを<++ {I)
        のscanf(" %D%D "、およびX&Y)。
        QRY [POS [Y]一back(POS [X])。QP [POS [Y]一back(I)。
    } 
    DFS2(0 )。
    (i = 0 ; iはQを<; ++ I)のprintf(" %Dを\ n " 、ANS [I])。
    リターン 0 ; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/sunshine-chen/p/11315767.html