zoukankan      html  css  js  c++  java
  • [bzoj2434] [Noi2011]阿狸的打字机

      AC自动机+树状数组。

      先把fail边反向建出fail树来。。

      第x个字符串在第y个字符串中出现了多少次。对于y的每个前缀,如果它结尾可以通过fail跳到x的结尾的话,那么就出现了x。。

      也就是查询x的fail子树中,有多少个y的节点。

      在trie上暴力跑,在树状数组上加入根到当前节点路径上的点(将对应dfn值所在的地方+1),

      跑到y的结束节点时,对于每个对应的查询x,求出x的子树中有多少个点就行了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ll long long
     6 using namespace std;
     7 const int maxn=100233;
     8 struct zs{int too,pre;}e[maxn],e1[maxn];int tot,last[maxn],tot1,last1[maxn];
     9 int too[maxn],pre[maxn],id[maxn],la[maxn],tt;
    10 int L[maxn],R[maxn],ed[maxn],tim;
    11 int t[maxn];
    12 int fail[maxn],ch[maxn][26],dl[maxn],fa[maxn];
    13 int i,j,k,n,m,cnt,node;
    14 int ans[maxn];
    15 char s[maxn];
    16  
    17 int ra;char rx;
    18 inline int read(){
    19     rx=getchar(),ra=0;
    20     while(rx<'0'||rx>'9')rx=getchar();
    21     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    22 }
    23 inline void insert(int a,int b){e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;}
    24 inline void getfail(){
    25     int l=0,r=1,i,now,p;dl[1]=0;
    26     while(l<r){
    27         now=dl[++l];
    28         for(i=0;i<26;i++)if(ch[now][i]){
    29             dl[++r]=ch[now][i];
    30             for(p=fail[now];p&&!ch[p][i];p=fail[p]);
    31             fail[ch[now][i]]=!now?0:ch[p][i],insert(fail[ch[now][i]],ch[now][i]);
    32         }
    33     }
    34 }
    35 void dfs(int x){
    36     L[x]=++tim;
    37     for(int i=last[x];i;i=e[i].pre)dfs(e[i].too);
    38     R[x]=tim;
    39 }
    40 inline void ins(int a,int b){too[++tt]=b,id[tt]=i,pre[tt]=la[a],la[a]=tt;}
    41 inline void insgg(int a,int b){e1[++tot1].too=b,e1[tot1].pre=last1[a],last1[a]=tot1;}
    42  
    43 inline void add(int x){while(x<=node)t[x]++,x+=x&-x;}
    44 inline void del(int x){while(x<=node)t[x]--,x+=x&-x;}
    45 inline int query(int l,int r){
    46     int sm=0;l--;
    47     while(r)sm+=t[r],r-=r&-r;
    48     while(l)sm-=t[l],l-=l&-l;return sm;
    49 }
    50 void dfs2(int x){
    51     int i,x1,y,j;//printf("in:   %d
    ",x);
    52     if(x)add(L[x]);
    53     for(i=last1[x];i;i=e1[i].pre)
    54         for(y=e1[i].too,j=la[y];j;j=pre[j])
    55             x1=too[j],ans[id[j]]=query(L[ed[x1]],R[ed[x1]]);
    56     for(i=0;i<26;i++)if(ch[x][i])/*printf("%d-->%d
    ",x,ch[x][i]),*/dfs2(ch[x][i]);
    57 //  printf("out:   %d
    ",x);
    58     if(x)del(L[x]);
    59 }
    60 int main(){
    61     scanf("%s",s+1),n=strlen(s+1);
    62     int now=0;
    63     for(i=1;i<=n;i++){
    64         if(s[i]=='P')cnt++,ed[cnt]=now,insgg(now,cnt);else
    65         if(s[i]=='B')now=fa[now];else
    66         if(!ch[now][s[i]-'a'])ch[now][s[i]-'a']=++node,fa[node]=now,now=node;
    67         else now=ch[now][s[i]-'a'];
    68     }node++;
    69     getfail();
    70     dfs(0);
    71     m=read();
    72     for(i=1;i<=m;i++)ins(read(),read());
    73     dfs2(0);
    74     for(i=1;i<=m;i++)printf("%d
    ",ans[i]);
    75 }
    View Code
  • 相关阅读:
    NET下RabbitMQ实践[WCF发布篇]
    基于Mongodb分布式存储物理文件
    NET下RabbitMQ实践[实战篇]
    关于Memcache mutex设计模式的.net实现
    使用ServiceStackRedis链接Redis简介
    NET下RabbitMQ实践[示例篇]
    基于MongoDB分布式存储进行MapReduce并行查询
    Asp.Net开发小技巧汇总
    愈敏洪讲座
    图标下载利器
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5623204.html
Copyright © 2011-2022 走看看