【bzoj3940】[Usaco2015 Feb]Censoring AC自动机

来源:互联网 发布:阿里云的免费虚拟主机 编辑:程序博客网 时间:2024/05/16 09:41

同3942,把KMP换成AC自动机。

开一个栈,记录一下每个位置匹配到哪个节点,如果是单词节点,那么弹出对应长度的字符串。


#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<iostream>#define maxn 110010  using namespace std; int ch[maxn][26],fail[maxn],q[maxn],w[maxn],dep[maxn];char s[maxn],st[maxn],s1[maxn];int n,m,tot,top,root; int newnode(){    tot++;    for (int i=0;i<26;i++) ch[tot][i]=-1;    return tot;} void insert(){    int n=strlen(s1+1),x=root;    for (int i=1;i<=n;i++)    {        if (ch[x][s1[i]-'a']==-1) ch[x][s1[i]-'a']=newnode();        x=ch[x][s1[i]-'a'];     }    dep[x]=n;} void build_fail(){    int l=0,r=0;    fail[root]=root;        for (int i=0;i<26;i++)      if (ch[root][i]==-1) ch[root][i]=root;      else      {        fail[ch[root][i]]=root;        q[++r]=ch[root][i];      }    while (l<r)    {        int x=q[++l];        for (int i=0;i<26;i++)          if (ch[x][i]==-1) ch[x][i]=ch[fail[x]][i];          else          {            fail[ch[x][i]]=ch[fail[x]][i];            q[++r]=ch[x][i];          }    }} int main(){    //freopen("data.in","r",stdin);    //freopen("data.out","w",stdout);    scanf("%s",s+1);    tot=0;root=newnode();    scanf("%d",&n);    for (int i=1;i<=n;i++)    {        scanf("%s",s1+1);        insert();    }    build_fail();    int x=root,len=strlen(s+1);w[0]=root;    for (int i=1;i<=len;i++)    {        st[++top]=s[i];        x=ch[x][s[i]-'a'];w[top]=x;        if (dep[x]) top-=dep[x],x=w[top];    }    for (int i=1;i<=top;i++) printf("%c",st[i]);printf("\n");    return 0;}


0 0
原创粉丝点击