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])を、 }