• 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;
    }
  • 相关阅读:
    6、linux中同步、互斥、阻塞(原子操作、信号量、阻塞)
    lightOJ-1199 Partitioning Game (SG函数)
    HDU-1013 Digital Roots
    HDU-1004 Let the Balloon Rise (STL map)
    HDU-1020 Encoding (字符串)
    POJ-2524 Ubiquitous Religions (并查集)
    POJ-1988 Cube Stacking (带权并查集)
    POJ-2236 Wireless Network (并查集)
    HDU-1002 A + B Problem II (模拟大数相加)
    HDU-1829 A Bug's Life (种类并查集)
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10424498.html
Copyright © 2020-2023  润新知