[ACオートマトン] [フェンウィックツリー] luogu P2414アリのタイプライター

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

 

分析

文字列Bのクエリ文字列の一部を簡単に見つけることの数は、チェーン内の各点を通るダンスはAの文字列の末尾に到達するために失敗した回数のアクセス列B、頼まれます

ツリーに出て行くうちに構築失敗ツリー、ポイントに相当し、それぞれに到達したが、重み1を失敗した場合、見つけることができます-1サブツリー失敗のツリーの最後にクエリ文字列、それは、配列Bの終わりに達した場合、残さ重みと

フェンウィックツリーDFS順序で、容易に解決することができます

 

#include <iostreamの> 
する#include <cstdioを> 
する#include <CStringの> 
する#include <キュー> 
の#include <アルゴリズム>
 の#define lowbit(x)はxおよび-x
 使用して 名前空間STD。
CONSTの INT N = 2E5 + 10 構造体グラフ{
     int型V、NX。
} G [N]。
int型GCNT、リスト[N];
INT T [N] [、[N]をフェイル26 ]、CNT、V [N]。
構造体クエリー{
     int型X、Y、ID。
} Q [N]。
int型M、LEN、TME、P。
INT L [N]、R [N]、エンド[N]、ANS [N] F [N]、。
CHARC [N]。

ボイド追加(INT U、INT V){ 
    G [ ++ GCNT] =(グラフ){V、リスト[U]};リスト[U] = GCNT。
} 

BOOL CMP(クエリ、クエリB){
     戻り AY < によって、
} 

ボイド挿入(){
     int型のx = 0、ID = 0 int型 I = 1、N = STRLEN(C + 1); iが<= N; iが++ ){
         場合(C [I] == ' B ' ){ 
            X = F [X]。
            持続する ;
        } 
        もし、(C [I] == ' P ' ){ 
            末端[ ++ ID] =のX。
            続け; 
        } 
        もし(!T [X] [I] [C - ' A ' ])T [X] [C [I] - F ' ' ] = ++ CNT] =のX。
        X = T [X] [C [I] - ' ' ]。
    } 
} ボイドビルド(){ 
    キュー < INT > Q。
    しばらく(!q.empty())q.pop();
    以下のためのint型 I = 0

; iは< 26 ; iは++)場合(T [ 0 ] [i])とq.pushを(Tは[ 0 ] [i])と、追加(0、T [ 0 ] [I])。
    一方、(!q.empty()){
         int型、U = q.front(); q.pop()。
        以下のためにint型 i = 0 ; iは< 26 ; iは++ 場合(Tは[U]は[i]は){
                 intは今= 失敗[U]。
                ながら(!今&& tは、[今] [i])となりました= [今]失敗します。
                失敗[T [U] [I] =
            } [今] T [i]は、(T [今] [I]、T [U] [I])を追加します。
                q.push(T [U] [I])。
    } 
} 

ボイド DFS(INT U){ 
    L [U]は = ++ TME。
    以下のためにint型 I =リスト[U]; I; I = G [i]が.nx)DFS(G [i]は.V)。
    R [U] = TMEと、
} 

ボイド ADDC(int型のx、int型C){
     ため(; X <= TME; X + = lowbit(x))をV [X] + = C。
} 

int型の合計(int型X){
     int型 ANS = 0 (; X; X- = lowbit(X))ANS + = V [X]。
    戻るANSを。
}

ボイドトライ(){
    INT X = 0 以下のためにint型 I = 1、N = STRLEN(C + 1); iは= N <; iは++ ){
         もし、(C [I] == ' B ' ){ 
            ADDC(L [x]は、 - 1); X = F [バツ];
            続け; 
        } 
        もし、(C [I] == ' P ' ){
             一方(端[Q [P] .Y] == x)はANS [Qを[P] .ID] =合計(R [END [Q [P]。 X]]) -合計(L [END [Q [P] .X]] - 1)、P ++ 継続 ;
        } 
        X - = tの[X] [I] [C' ' ]; ADDC(L [x]は、1 )。
    } 
} int型のmain(){ 
    scanf関数(" %sの"、C + 1 )。
    インサート(); 
    scanf関数(" %のD "、&M)。
    以下のためにint型 iは= 1 ; I <= M; iは++)のscanf(" %d個の%のD "、&​​Q [i]は.X、&Qを[I]・Y)、Q [i]は.ID = I。
    ソート(Q + 1、Q + M + 1 、CMP)。
    ビルドします(); 
    DFS(0

)。
    P = 1 ; LEN = 0 ;トライ()。
    以下のためにint型私= 1 ; I <= M; iが++)のprintf(" %d個の\ n " 、ANS [I])を、
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/mastervan/p/11324875.html