lalala

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<queue>  
#define N 100003  
using namespace std;  
int n,m,len,t[N],tail,sz,num,next[N*2],point[N],v[N*2],c[N*2],pl[N],tot=-1;  
char s[1000000];  
int ch[N][30],fail[N],isend[N],pos[N],h[N*2],fa[N],dis[N],a[N*2],ans[N];  
int l[N],r[N],sz1;  
struct data  
{  
 int x,y,p;  
};data ask[N];  
int cmp(data a,data b)  
{  
  return a.y<b.y;  
}  
void add(int x,int y)  
{  
 tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y;  
}  
void insert()  
{  
  int now=0;  
  for (int i=0;i<len;i++)  
  {  
  int x=s[i]-'a';  
  if (s[i]=='P')  ++num,isend[now]=num,pos[num]=now,pl[i]=num;  
  else  
  if (s[i]=='B') now=fa[now];  
  else  
  {  
   if (!ch[now][x]) ch[now][x]=++sz;  
   fa[ch[now][x]]=now;  
   now=ch[now][x];  
   dis[i]=now;  
  }  
  }  
}  
void makefail()  
{  
    queue<int> p;  
    for (int i=0;i<26;i++)  
     if (ch[0][i]) p.push(ch[0][i]),add(0,ch[0][i]);  
    while (!p.empty())  
    {  
      int now=p.front(); p.pop();  
      for (int i=0;i<26;i++)  
      {  
        if (!ch[now][i])  
        {  
         ch[now][i]=ch[fail[now]][i];  
         continue;  
        }  
        int x=ch[now][i];  
        fail[x]=ch[fail[now]][i];  
       // if (ch[fail[now]][i])   
         add(fail[x],x);  
        p.push(x);  
      }  
    }  
}  
int lowbit(int x)  
{  
  return x&(-x);  
}  
void change(int x,int v)  
{  
  for (int i=x;i<=sz1;i+=lowbit(i))  
   a[i]+=v;  
}  
int sum(int x)  
{  
 int ans=0;  
 while (x>0)  
 {  
  ans+=a[x];  
  x-=lowbit(x);  
 }  
 return ans;  
}  
void dfs(int  now)  
{  
  l[now]=++sz1;  
  h[sz]=now;  
  for (int i=point[now];i!=-1;i=next[i])  
   dfs(v[i]);  
  r[now]=sz1;  
}  
int main()  
{  
 freopen("a.in","r",stdin);  
 memset(point,-1,sizeof(point));
 memset(next,-1,sizeof(next));
 scanf("%s",s);  
 len=strlen(s);  
 insert();  
 makefail();  
 dfs(0);  
 scanf("%d",&n);  
 for (int i=1;i<=n;i++)  
  scanf("%d%d",&ask[i].x,&ask[i].y),ask[i].p=i;  
 /*for (int i=1;i<=n;i++) 
 cout<<ask[i].x<<" "<<ask[i].y<<" "<<ask[i].p<<endl; 
 for (int i=1;i<=len;i++) 
  cout<<pos[i]<<" "; 
 cout<<endl; 
 for (int i=1;i<=len;i++) 
  cout<<pl[i]<<" "; 
 cout<<endl; 
 for (int i=1;i<=len;i++) 
  cout<<isend[i]<<" "; 
 cout<<endl; */
 for (int i=0;i<=num;i++) 
  cout<<l[i]<<" "<<r[i]<<endl;
 for (int i=0;i<=n;i++)
  cout<<point[i]<<" ";
 cout<<endl;
 sort(ask+1,ask+n+1,cmp); int j=1;  
 for (int i=0;i<len;i++)  
 {  
  if (s[i]=='P')    
   {  
     while (ask[j].y==pl[i])  
      ans[ask[j].p]=sum(r[dis[ask[j].x]])-sum(l[dis[ask[j].x]]),j++;  
   }  
  else    
  if (s[i]=='B') change(l[dis[i-1]],-1);  
  else  change(l[dis[i]],1);  
 }  
 for (int i=1;i<=n;i++)  
  printf("%d\n",ans[i]);  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值