zoukankan      html  css  js  c++  java
  • BZOJ3483 : SGU505 Prefixes and suffixes(询问在线版)

    将每个串正着插入Trie A中,倒着插入Trie B中。

    并求出每个串在A,B中的dfs序。

    每次查询等价于查询在A中dfs序在[la,ra]之间,在B中dfs序在[lb,rb]之间的串的个数,用主席树维护即可。

    #include<cstdio>
    const int S=2000010,N=2010,M=N*22;
    char s[S],ch;
    int n,m,i,j,k,posa[N],posb[N],g[S],v[N],nxt[N],ed,la,lb,ra,rb,ans;
    inline void read(){
      while(!(((ch=getchar())>='a')&&(ch<='z')));
      s[k=1]=(ch-'a'+ans)%26;
      while(((ch=getchar())>='a')&&(ch<='z'))s[++k]=(ch-'a'+ans)%26;
    }
    inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
    struct Trie{
    int tot,son[S][26],st[S],en[S],dfn;
    inline int ins0(){
      int x=0;
      for(int i=1;i<=k;i++){
        if(!son[x][s[i]])son[x][s[i]]=++tot;
        x=son[x][s[i]];
      }
      return x;
    }
    inline int ins1(){
      int x=0;
      for(int i=k;i;i--){
        if(!son[x][s[i]])son[x][s[i]]=++tot;
        x=son[x][s[i]];
      }
      return x;
    }
    void dfs(int x){
      st[x]=++dfn;
      for(int i=0;i<26;i++)if(son[x][i])dfs(son[x][i]);
      en[x]=dfn;
    }
    inline void ask0(){
      int x=0;
      for(int i=1;i<=k;i++){
        if(!son[x][s[i]]){la=ra=0;return;}
        x=son[x][s[i]];
      }
      la=st[x],ra=en[x];
    }
    inline void ask1(){
      int x=0;
      for(int i=k;i;i--){
        if(!son[x][s[i]]){lb=rb=0;return;}
        x=son[x][s[i]];
      }
      lb=st[x],rb=en[x];
    }
    }A,B;
    int l[M],r[M],val[M],tot,T[S];
    int ins(int x,int a,int b,int c){
      int y=++tot;val[y]=val[x]+1;
      if(a==b)return y;
      int mid=(a+b)>>1;
      if(c<=mid)l[y]=ins(l[x],a,mid,c),r[y]=r[x];else l[y]=l[x],r[y]=ins(r[x],mid+1,b,c);
      return y;
    }
    int ask(int x,int a,int b){
      if(!x)return 0;
      if(lb<=a&&b<=rb)return val[x];
      int mid=(a+b)>>1,t=0;
      if(lb<=mid)t=ask(l[x],a,mid);
      if(rb>mid)t+=ask(r[x],mid+1,b);
      return t;
    }
    int main(){
      scanf("%d",&n);
      for(i=1;i<=n;i++){
        read();
        posa[i]=A.ins0();
        posb[i]=B.ins1();
      }
      A.dfs(0),B.dfs(0);
      for(i=1;i<=n;i++)add(A.st[posa[i]],B.st[posb[i]]);
      for(i=1;i<=A.dfn;i++)for(T[i]=T[i-1],j=g[i];j;j=nxt[j])T[i]=ins(T[i],1,B.dfn,v[j]);
      scanf("%d",&m);
      while(m--){
        read(),A.ask0();
        read(),B.ask1();
        if(la&&lb)ans=ask(T[ra],1,B.dfn)-ask(T[la-1],1,B.dfn);else ans=0;
        printf("%d
    ",ans);
      }
      return 0;
    }
    

      

  • 相关阅读:
    2015-03-20——移动端UC浏览器、QQ浏览器自动全屏
    2015-03-18——mongodb的简单配置
    2015-03-12——简析DOM2级样式
    2015-03-12——简析DOM2级事件
    2015-03-11——简析DOM规范
    2015-03-10——简析javascript对象
    分页控件的编写
    Jquery添加掩盖层的插件
    正则表达式/g/i/d
    MVC请求生命周期
  • 原文地址:https://www.cnblogs.com/clrs97/p/4630975.html
Copyright © 2011-2022 走看看