1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <queue> #include<assert.h> using namespace std; #define MAXN 1000006 #define mod 1000000007 int n , m; int len; char ch[MAXN] , zh[MAXN]; int en; int son[MAXN][26] , fa[MAXN] , fail[MAXN] , num[MAXN] , idx , to[MAXN]; int cid = 0;
int head1[MAXN] , tt1[MAXN << 1] , nex1[MAXN << 1] , ecn1; void ade1( int u , int v ) {
tt1[++ ecn1] = v , nex1[ecn1] = head1[u] , head1[u] = ecn1; }
int now = 0 , tim = 0; void ins( char* ch , int id ) {
for( int i = 0 ; i < len ; ++ i ) {
if( !son[now][ch[i] - 'a'] ) son[now][ch[i] - 'a'] = ++ idx , fa[idx] = now , ade1( now , idx ); now = son[now][ch[i] - 'a']; } ++ num[now] , to[id] = now; }
int head[MAXN] , tt[MAXN << 1] , nex[MAXN << 1] , ecn; void ade( int u , int v ) {
tt[++ ecn] = v , nex[ecn] = head[u] , head[u] = ecn; }
void build( ) { queue<int> Q; for( int i = 0 ; i < 26 ; ++ i ) if( son[0][i] ) Q.push( son[0][i] ); while( !Q.empty() ) { int cur = Q.front( ); Q.pop( ); ade( fail[cur] , cur ); for( int i = 0 ; i < 26 ; ++ i ) if( son[cur][i] ) fail[son[cur][i]] = son[fail[cur]][i] , Q.push( son[cur][i] ); else son[cur][i] = son[fail[cur]][i]; } } struct que { int t , s , id; } Q[MAXN] ; bool cmp( que a , que b ) { return a.s < b.s; } int dfn[MAXN] , R[MAXN] , clo; void dfs( int u , int fa ) { dfn[u] = ++ clo; for( int i = head[u] ; i ; i = nex[i] ) { int v = tt[i]; dfs( v , u ); } R[u] = clo; }
namespace fwk { int T[MAXN]; void add( int u , int c ) { assert( u ); while( u < MAXN ) T[u] += c , u += ( u & -u ); } int sum( int u ) { int ret = 0; while( u > 0 ) ret += T[u] , u -= ( u & -u ); return ret; } } vector<pair<int,int> > ques[MAXN]; int ans[MAXN]; void dfs1( int u ) { fwk::add( dfn[u] , 1 ); for( int i = 0 ; i < ques[u].size() ; ++ i ) ans[ques[u][i].second] = fwk::sum( R[ques[u][i].first] ) - fwk::sum( dfn[ques[u][i].first] - 1 ); for( int i = head1[u] ; i ; i = nex1[i] ) { int v = tt1[i]; dfs1( v ); } fwk::add( dfn[u] , -1 ); }
int main( ) {
scanf("%s",ch); n = strlen( ch ); for( int i = 0 ; i < n ; ++ i ) { if( ch[i] == 'P' ) ins( zh , ++ cid ) , len = 0; else if( ch[i] == 'B' ) { if( len ) -- len; else now = fa[now]; } else zh[len ++] = ch[i]; } build( ); dfs( 0 , 0 ); cin >> m; for( int i = 1 , t , s ; i <= m ; ++ i ) scanf("%d%d",&t ,&s ) , ques[to[s]].push_back( make_pair( to[t] , i ) ); dfs1( 0 );
for( int i = 1 ; i <= m ; ++ i ) printf("%d\n",ans[i]); }
|