您的位置:首页 > Web前端

洛谷 P3121 [USACO15FEB]审查(黄金)Censoring (Gold) 【AC自动机+栈】

2018-05-09 11:46 489 查看

这个和bzoj同名题不一样,有多个匹配串
但是思路是一样的,写个AC自动机,同样是开两个栈,一个存字符,一个存当前点在trie树上的位置,然后如果到了某个匹配串的末尾,则弹栈

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=100005;
int n,t
,top;
char a
,b
,s
;
struct AC
{
int tot,c
[27],f
,l
;
void ins(char s[])
{
int len=strlen(s),nw=0;
for(int i=0;i<len;i++)
{
if(!c[nw][s[i]-'a'])
c[nw][s[i]-'a']=++tot;
nw=c[nw][s[i]-'a'];
}
l[nw]=len;
}
void build()
{
queue<int>q;
for(int i=0;i<26;i++)
if(c[0][i])//!!!!!!!!!!!!!!!!!!!!!!!!!!!
f[c[0][i]]=0,q.push(c[0][i]);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(c[u][i])
f[c[u][i]]=c[f[u]][i],q.push(c[u][i]);
else
c[u][i]=c[f[u]][i];
}
}
}
void wk(char a[])
{
int len=strlen(a),nw=0;
for(int i=0;i<len;i++)
{
nw=c[nw][a[i]-'a'];
s[++top]=a[i],t[top]=nw;
if(l[nw])
top-=l[nw],nw=t[top];
}
for(int i=1;i<=top;i++)
putchar(s[i]);
}
}ac;
int main()
{
scanf("%s%d",a,&n);
for(int i=1;i<=n;i++)
{
scanf("%s",b);
ac.ins(b);
}
ac.build();
ac.wk(a);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: