• 【BZOJ 2434】 [Noi2011]阿狸的打字机 fail树+树状数组


    就是考了一个fail树的神奇应用我们建出fail树之后,发现我们就是在求y到根的路径上所有的点在以x为根的子树里的个数,这个我们离线后用树状数组+dfs序即可解决

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    const int N=100010;
    char s[N];
    struct Trie{
      int ch[26],fail,fa,deep;
    }node[N];
    std::vector<int> mem[N];
    int sz;
    struct V{
      int to,next;
    }c[N];
    struct VQ{
      int to,next,id;
    }ques[N];
    int head[N],t,num,ques_head[N],ques_t;
    int belong[N],q[N],l[N],r[N],Time;
    int T[N],ans[N],m,n;
    inline int Q(int pos){
      int ret=0;
      for(;pos>0;pos-=pos&(-pos))
        ret+=T[pos];
      return ret;
    }
    inline void U(int pos,int key){
      for(;pos<=n;pos+=pos&(-pos))
        T[pos]+=key;
    }
    inline void add(int x,int y){
      c[++t].to=y,c[t].next=head[x],head[x]=t;
    }
    inline void ques_add(int x,int y,int z){
      ques[++ques_t].to=y,ques[ques_t].next=ques_head[x],ques_head[x]=ques_t,ques[ques_t].id=z;
    }
    void dfs(int x){
      l[x]=++Time;
      for(int i=head[x];i;i=c[i].next)
        dfs(c[i].to);
      r[x]=Time;
    }
    void dfs_(int x){
      U(l[x],1);
      for(int i=0;i<mem[x].size();i++)
        for(int j=ques_head[mem[x][i]];j;j=ques[j].next)
          ans[ques[j].id]=Q(r[belong[ques[j].to]])-Q(l[belong[ques[j].to]]-1);
      for(int i=0;i<26;i++)
        if(node[node[x].ch[i]].deep>node[x].deep)
          dfs_(node[x].ch[i]);
      U(l[x],-1);
    }
    int main(){
      scanf("%s",s);
      int now=0;
      for(int i=0;s[i];i++){
        if(s[i]=='P'){
          belong[++num]=now;
          mem[now].push_back(num);
          continue;
        }
        if(s[i]=='B'){
          now=node[now].fa;
          continue;
        }
        if(!node[now].ch[s[i]-'a'])node[now].ch[s[i]-'a']=++sz,node[sz].fa=now,node[sz].deep=node[now].deep+1;
        now=node[now].ch[s[i]-'a'];
      }
      n=sz+1;
      q[0]=0;
      for(int i=0,j=0;i<=j;i++)
        for(int l=0;l<26;l++)
          if(node[q[i]].ch[l]){
            q[++j]=node[q[i]].ch[l];
            node[q[j]].fail=q[i]?node[node[q[i]].fail].ch[l]:0;
            add(node[q[j]].fail,q[j]);
          }else
            node[q[i]].ch[l]=q[i]?node[node[q[i]].fail].ch[l]:0;
      dfs(0);
      scanf("%d",&m);
      for(int i=1,x,y;i<=m;i++)
        scanf("%d%d",&x,&y),ques_add(y,x,i);
      dfs_(0);
      for(int i=1;i<=m;i++)
        printf("%d
    ",ans[i]);
      return 0;
    } 
  • 相关阅读:
    引用 AspNetCoreRateLimit => StatusCode cannot be set because the response has already started.
    Sublime Json 格式化
    gitlab 建立本地仓库
    R语言 启动报错 *** glibc detected *** /usr/lib64/R/bin/exec/R: free(): invalid next size (fast): 0x000000000263a420 *** 错误 解决方案
    范数
    SparkR-Install
    R语言扩展包dplyr——数据清洗和整理
    R语言与机器学习学习笔记
    sparkR原理
    data.frame类型数据如何将第一列值替换为行号
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7517652.html
Copyright © 2020-2023  润新知