1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #define M 100008
  5 using namespace std;
  6 char ch[M];
  7 int cnt=1,pos[M],now,fa[M],fail[M],q[M],head[M],next[M],u[M],cnt1,m,n;
  8 int a[M][26],head1[M],next1[M],u1[M],T,l[M],r[M],an[M],su[2*M];
  9 void build()
 10 {
 11     int h=0,t=1;
 12     q[1]=1;
 13     for(;h<t;)
 14       {
 15         int p=q[++h];
 16         for(int i=1;i<=26;i++)
 17           if(a[p][i])
 18             {
 19                 int now=fail[p];
 20                 q[++t]=a[p][i];
 21                 for(;!a[now][i];now=fail[now]);
 22                 fail[a[p][i]]=a[now][i];
 23             }
 24       }
 25     return;
 26 }
 27 void jia(int a1,int a2)
 28 {
 29     cnt1++;
 30     u[cnt1]=a2;
 31     next[cnt1]=head[a1];
 32     head[a1]=cnt1;
 33     return;
 34 }
 35 void dfs(int a1)
 36 {
 37     l[a1]=++T;
 38     for(int i=head[a1];i;i=next[i])
 39       dfs(u[i]);
 40     r[a1]=++T;
 41 }
 42 int xun(int a1)
 43 {
 44     int sum=0;
 45     for(int i=a1;i;i-=i&-i)
 46       sum+=su[i];
 47     return sum;
 48 }
 49 void add(int a1,int a2)
 50 {
 51     for(int i=a1;i<=T;i+=i&-i)
 52       su[i]+=a2;
 53 }
 54 int main()
 55 {
 56     scanf("%s",ch+1);
 57     now=1;
 58     n=strlen(ch+1);
 59     for(int i=1;i<=n;i++)
 60       if(ch[i]=='P')
 61         {
 62             pos[0]++;
 63             pos[pos[0]]=now;
 64         }
 65       else if(ch[i]=='B')
 66              now=fa[now];
 67            else
 68              {
 69                if(!a[now][ch[i]-96])
 70                  {
 71                     cnt++;
 72                     a[now][ch[i]-96]=cnt;
 73                     fa[cnt]=now;
 74                  }
 75                now=a[now][ch[i]-96];
 76              }
 77     for(int i=1;i<=26;i++)
 78       a[0][i]=1;
 79     build();
 80     for(int i=1;i<=cnt;i++)
 81       jia(fail[i],i);
 82     scanf("%d",&m);
 83     for(int i=1;i<=m;i++)
 84        {
 85           int x,y;
 86           scanf("%d%d",&x,&y);
 87           u1[i]=x;
 88           next1[i]=head1[y];
 89           head1[y]=i;
 90        }
 91     dfs(1);
 92     now=1;
 93     pos[0]=0;
 94     for(int i=1;i<=n;i++)
 95       if(ch[i]=='P')
 96         {
 97             pos[0]++;
 98             for(int i=head1[pos[0]];i;i=next1[i])
 99               an[i]=xun(r[pos[u1[i]]])-xun(l[pos[u1[i]]]-1);
100         }
101       else  if(ch[i]=='B')
102               {
103                 add(l[now],-1);
104                 now=fa[now];
105               }  
106             else
107               {
108                 now=a[now][ch[i]-96];
109                 add(l[now],1);
110               }
111     for(int i=1;i<=m;i++)
112       printf("%d\n",an[i]);
113     return 0;
114 }

AC自动机 根据dfs序建立fail树(就是将失败指针反向),每次查询x子树中有多少y的节点。

posted on 2016-03-21 23:20  xiyuedong  阅读(123)  评论(0编辑  收藏  举报