zoukankan      html  css  js  c++  java
  • 「luogu2414」[NOI2011]阿狸的打字机

    建出AC自动机,获得fail树,发现问题转化成求以x为根的子树中有多少个属于y串的节点。

    求出fail树的dfs序,由dfs序的性质可知以x为根的子树在dfs序上是连续的。

    在trie树中跑一边dfs,dfs过程中用树状数组统计答案即可。

    注意fail树的节点数是tot+1。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=100010;
     4 char ss[N];
     5 int n,m,tot,spos[N]; //spos[i]:串i在trie树中的位置
     6 int pre[N],ch[N][26],fail[N];
     7 int qx[N],qy[N],ans[N],bit[N];
     8 vector<int>g[N],curq[N];
     9 inline void build_trie(char* s){
    10     int l=strlen(s),now=0;
    11     for(int i=0;i<l;i++){
    12         if(s[i]=='B') now=pre[now];
    13         else if(s[i]=='P') spos[++n]=now;
    14         else{
    15             int c=s[i]-'a';
    16             if(!ch[now][c]) ch[now][c]=++tot,pre[tot]=now;
    17             now=ch[now][c];
    18         }
    19     }
    20     return;
    21 }
    22 inline void build_fail(){
    23     queue<int>q;
    24     for(int i=0;i<26;i++)if(ch[0][i]){
    25         q.push(ch[0][i]);
    26         g[0].push_back(ch[0][i]);
    27     }
    28     int x;
    29     while(!q.empty()){
    30         x=q.front();q.pop();
    31         for(int i=0;i<26;i++)if(ch[x][i]){
    32             q.push(ch[x][i]);
    33             int j=fail[x];
    34             while(j&&!ch[j][i]) j=fail[j];
    35             fail[ch[x][i]]=ch[j][i];
    36             g[ch[j][i]].push_back(ch[x][i]);
    37         }
    38     }
    39     return;
    40 }
    41 int fa[N],id[N],siz[N],dfn;
    42 void dfs(int k,int father){
    43     id[k]=++dfn,fa[k]=father,siz[k]=1;
    44     for(int i=0;i<g[k].size();i++){
    45         int x=g[k][i];
    46         if(x==father) continue;
    47         dfs(x,k);
    48         siz[k]+=siz[x];
    49     }
    50     return;
    51 }
    52 inline int lowbit(int k){return k&(-k);}
    53 inline void bitadd(int pos,int x){
    54     while(pos<=tot+1) bit[pos]+=x,pos+=lowbit(pos);
    55     return;
    56 }
    57 inline int bitque(int pos){
    58     int ans=0;
    59     while(pos) ans+=bit[pos],pos-=lowbit(pos);
    60     return ans;
    61 }
    62 void dfs_trie(int k){
    63     bitadd(id[k],1);
    64     for(int i=0;i<curq[k].size();i++){
    65         int x=curq[k][i];
    66         ans[x]=bitque(id[spos[qx[x]]]+siz[spos[qx[x]]]-1)-bitque(id[spos[qx[x]]]-1);
    67     }
    68     for(int i=0;i<26;i++)if(ch[k][i]){
    69         dfs_trie(ch[k][i]);
    70     }
    71     bitadd(id[k],-1);
    72     return;
    73 }
    74 int main(){
    75     scanf("%s",ss);
    76     build_trie(ss);
    77     build_fail();
    78     dfs(0,-1);
    79     scanf("%d",&m);
    80     for(int i=1;i<=m;i++){
    81         scanf("%d%d",&qx[i],&qy[i]);
    82         curq[spos[qy[i]]].push_back(i);
    83     }
    84     dfs_trie(0);
    85     for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    86     return 0;
    87 }
  • 相关阅读:
    [Python Study Notes]进程信息(丁丁软件监控进程,http-post)
    [Python Study Notes]cpu信息
    [Python Study Notes]电池信息
    [Python Study Notes]内存信息
    [Python Study Notes]磁盘信息和IO性能
    [Python Study Notes]计算cpu使用率v0.1
    [Python Study Notes]计算cpu使用率
    [Python Study Notes]psutil模块
    [解决问题] E: 无法获得锁 /var/lib/dpkg/lock
    [Python Study Notes] python面试题总结
  • 原文地址:https://www.cnblogs.com/mycups/p/8565572.html
Copyright © 2011-2022 走看看