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

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #define M 100008
      5 using namespace std;
      6 char ch[M];
      7 int cnt=1,pos[M],now,fa[M],fail[M],q[M],head[M],next[M],u[M],cnt1,m,n;
      8 int a[M][26],head1[M],next1[M],u1[M],T,l[M],r[M],an[M],su[2*M];
      9 void build()
     10 {
     11     int h=0,t=1;
     12     q[1]=1;
     13     for(;h<t;)
     14       {
     15         int p=q[++h];
     16         for(int i=1;i<=26;i++)
     17           if(a[p][i])
     18             {
     19                 int now=fail[p];
     20                 q[++t]=a[p][i];
     21                 for(;!a[now][i];now=fail[now]);
     22                 fail[a[p][i]]=a[now][i];
     23             }
     24       }
     25     return;
     26 }
     27 void jia(int a1,int a2)
     28 {
     29     cnt1++;
     30     u[cnt1]=a2;
     31     next[cnt1]=head[a1];
     32     head[a1]=cnt1;
     33     return;
     34 }
     35 void dfs(int a1)
     36 {
     37     l[a1]=++T;
     38     for(int i=head[a1];i;i=next[i])
     39       dfs(u[i]);
     40     r[a1]=++T;
     41 }
     42 int xun(int a1)
     43 {
     44     int sum=0;
     45     for(int i=a1;i;i-=i&-i)
     46       sum+=su[i];
     47     return sum;
     48 }
     49 void add(int a1,int a2)
     50 {
     51     for(int i=a1;i<=T;i+=i&-i)
     52       su[i]+=a2;
     53 }
     54 int main()
     55 {
     56     scanf("%s",ch+1);
     57     now=1;
     58     n=strlen(ch+1);
     59     for(int i=1;i<=n;i++)
     60       if(ch[i]=='P')
     61         {
     62             pos[0]++;
     63             pos[pos[0]]=now;
     64         }
     65       else if(ch[i]=='B')
     66              now=fa[now];
     67            else
     68              {
     69                if(!a[now][ch[i]-96])
     70                  {
     71                     cnt++;
     72                     a[now][ch[i]-96]=cnt;
     73                     fa[cnt]=now;
     74                  }
     75                now=a[now][ch[i]-96];
     76              }
     77     for(int i=1;i<=26;i++)
     78       a[0][i]=1;
     79     build();
     80     for(int i=1;i<=cnt;i++)
     81       jia(fail[i],i);
     82     scanf("%d",&m);
     83     for(int i=1;i<=m;i++)
     84        {
     85           int x,y;
     86           scanf("%d%d",&x,&y);
     87           u1[i]=x;
     88           next1[i]=head1[y];
     89           head1[y]=i;
     90        }
     91     dfs(1);
     92     now=1;
     93     pos[0]=0;
     94     for(int i=1;i<=n;i++)
     95       if(ch[i]=='P')
     96         {
     97             pos[0]++;
     98             for(int i=head1[pos[0]];i;i=next1[i])
     99               an[i]=xun(r[pos[u1[i]]])-xun(l[pos[u1[i]]]-1);
    100         }
    101       else  if(ch[i]=='B')
    102               {
    103                 add(l[now],-1);
    104                 now=fa[now];
    105               }  
    106             else
    107               {
    108                 now=a[now][ch[i]-96];
    109                 add(l[now],1);
    110               }
    111     for(int i=1;i<=m;i++)
    112       printf("%d
    ",an[i]);
    113     return 0;
    114 }

    AC自动机 根据dfs序建立fail树(就是将失败指针反向),每次查询x子树中有多少y的节点。

  • 相关阅读:
    (转) Linux下Setuid命令!
    Linux SWAP 交换分区配置说明(转)
    linux中ctime,mtime,atime的区别
    无法访问win8默认共享(如C$)解决办法
    Daemon进程
    autofs文件自动挂载系统
    Selinux相关
    解读linux中用户密码规则及忘记root口令的破解(思路)
    windows共享连接显示无法打开
    DOS口令启用停用的管理员密码
  • 原文地址:https://www.cnblogs.com/xydddd/p/5304307.html
Copyright © 2011-2022 走看看