AC自动机——Luogu3121 [USACO15FEB]审查(黄金)Censoring (Gold)

来源:互联网 发布:广东奥飞数据科技 编辑:程序博客网 时间:2024/06/07 10:30

https://www.luogu.org/problem/show?pid=3121
这题嘛。。。AC自动机
我们在匹配的时候可以开一个栈,一开始栈内为空,匹配时依次加入字母的位置,当匹配完成时把这个单词弹出继续操作就好了
其他没啥变化
具体看这段代码啦

inline void getans(int l){    int now=0;    for(int i=1;i<=l;i++){        now=p[now][s[i]-'a'];        pr[++sum]=now;rp[sum]=i;        if(b[now]){//以下下弹栈操作            sum-=b[now];            now=pr[sum];        }    }}

好像被数据坑了,据lc233说,按照一开始的bfs求fail写法会超时。。。
所以换了一个模板。。。
不多说,上代码吧

#include<bits/stdc++.h>using namespace std;char s[100001],c[100001];int n,np=0,q[100001],p[100001][26],fail[100001];int rp[100001],pr[100001],b[100001],sum=0;inline void insert(){    int now=0,l=strlen(c+1);    for(int i=1;i<=l;i++){        int t=c[i]-'a';        if(!p[now][t])p[now][t]=++np;        now=p[now][t];    }    b[now]=l;}inline void bfs(){    int l,r;l=r=0;    for(int i=0;i<26;i++)if(p[0][i])q[++r]=p[0][i];    while(l<r){        l++;        int t=q[l];        for(int i=0;i<26;i++)if(!p[t][i])p[t][i]=p[fail[t]][i];        else{            q[++r]=p[t][i];            fail[p[t][i]]=p[fail[t]][i];        }    }}inline void getans(int l){    int now=0;    for(int i=1;i<=l;i++){        now=p[now][s[i]-'a'];        pr[++sum]=now;rp[sum]=i;        if(b[now]){            sum-=b[now];            now=pr[sum];        }    }}int main(){    scanf("%s",s+1);    scanf("%d",&n);    for(int i=1;i<=n;i++)scanf("%s",c+1),insert();    bfs();    int l=strlen(s+1);getans(l);    for(int i=1;i<=sum;i++)printf("%c",s[rp[i]]);    return 0;}
1 0
原创粉丝点击