p2414 [NOI2011]阿狸的打字机

传送门

分析

咕咕咕

坑点就是没有本质相同的字符串且x<=y

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
char s[200100];
int n,m,trie[200100][26],fail[200100],fa[200100],cnt;
int Trie[200100][26],bel[200100],a[200100],ans[200100];
int dfn[200100],fin[200100],tot,le[200100],ri[200100];
int head[400100],nxt[400100],to[400100],S;
inline void ADD(int x,int y){
    nxt[++S]=head[x];
    head[x]=S;
    to[S]=y;
    nxt[++S]=head[y];
    head[y]=S;
    to[S]=x;
}
struct node {
    int x,y,id;
};
node q[200100];
vector<int>v[200100];
inline void build(){
    int i,j,k,p=0;
    k=strlen(s);
    for(i=0;i<k;i++)
      if(islower(s[i])){
          if(!trie[p][s[i]-'a']){
            trie[p][s[i]-'a']=++cnt;
            fa[cnt]=p;
          }
          p=trie[p][s[i]-'a'];
      }else if(s[i]=='B')p=fa[p];
       else a[++n]=p,bel[p]=n;
}
queue<int>qq;
inline void getfail(){
    int i,j,k;
    for(i=0;i<26;i++)
      if(trie[0][i]){
          fail[trie[0][i]]=0;
          qq.push(trie[0][i]);
      }
    while(!qq.empty()){
      int p=qq.front();
      qq.pop();
      for(i=0;i<26;i++)
        if(trie[p][i]){
          fail[trie[p][i]]=trie[fail[p]][i];
          qq.push(trie[p][i]);
        }else trie[p][i]=trie[fail[p]][i];
    }
}
inline void dfs(int x){
    dfn[x]=++tot;
    for(int i=head[x];i;i=nxt[i])
      if(!dfn[to[i]])dfs(to[i]);
    fin[x]=tot;
}
inline bool cmp(const node x,const node y){
    return x.y<y.y;
}
int d[200100];
inline int lb(int x){return x&(-x);}
inline void add(int x,int k){while(x<=tot)d[x]+=k,x+=lb(x);}
inline int que(int x){int res=0;while(x)res+=d[x],x-=lb(x);return res;}
inline void work(int x){
    add(dfn[x],1);
    if(bel[x]){
      for(int i=le[bel[x]];i<=ri[bel[x]];i++)
        ans[q[i].id]=que(fin[a[q[i].x]])-que(dfn[a[q[i].x]]-1);
    }
    for(int i=0;i<26;i++)
      if(Trie[x][i])work(Trie[x][i]);
    add(dfn[x],-1);
}
int main(){
    int i,j,k,Q;
    scanf("%s",s);
    build();
    for(i=0;i<=cnt;i++)
      for(j=0;j<26;j++)
        Trie[i][j]=trie[i][j];
    getfail();
    for(i=1;i<=cnt;i++)ADD(fail[i],i);
    dfs(0);
    scanf("%d",&Q);
    for(i=1;i<=Q;i++)scanf("%d%d",&q[i].x,&q[i].y),q[i].id=i;
    sort(q+1,q+Q+1,cmp);
    for(i=1,k=1;i<=Q;i=k){
      le[q[i].y]=i;
      while(q[k].y==q[i].y)k++;
      ri[q[i].y]=k-1;
    }
    work(0);
    for(i=1;i<=Q;i++)printf("%d
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/yzxverygood/p/10424498.html