zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    模拟实现bind、call、apply函数
    模拟实现ECMAScript5新增的数组方法
    HBuilder mui页面间传值的几种方式
    手机端软键盘弹出挤压页面的问题
    js获取当前时间
    原生js根据class获取元素的方法
    jquery之获取select选中的值
    原生js获取元素属性值方法
    利用javascrit获取url传递的参数
    jQuery图片预加载(延迟加载)之插件Lazy Load
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10424498.html
Copyright © 2011-2022 走看看