您的位置:首页 > 其它

AC自动机模板 2

2018-03-24 15:34 274 查看
题目:AC自动机(加强版)

资料:yyb大佬的博客

注意:这个题为了防止tle,需要加上优化,即 if(!ch[u][i]) ch[u][i]=ch[fail[u]][i]

代码:#include<bits/stdc++.h>
using namespace std;

#define maxn 150
#define maxd 70
#define maxm maxn*maxd
#define maxa 1000000
#define s 26

int n;

struct AC {
int ch[maxm+5][s+5],m;
int val[maxm+5];
char a[maxa+5];
int fail[maxm+5];
char lst[maxn+5][maxd+5];
int mp[maxn+5];
int sum[maxm+5];

void clr() {
memset(ch,0,sizeof(ch));
memset(val,0,sizeof(val));
memset(fail,0,sizeof(fail));
memset(mp,0,sizeof(mp));
memset(sum,0,sizeof(sum));
m=0;
}

void insert(char* x,int len,int j) {
int u=0;
for(int i=0; i<len; i++) {
int y=x[i]-'a'+1;
if(!ch[u][y]) {
ch[u][y]=++m;
}
u=ch[u][y];
}
val[u]++;
mp[j]=u;
}

void make_fail() {
queue<int> que;
for(int i=1; i<=s; i++) {
if(ch[0][i]) que.push(ch[0][i]);
}
while(!que.empty()) {
int u=que.front();
que.pop();
for(int i=1; i<=s; i++) {
if(ch[u][i]) {
que.push(ch[u][i]);
fail[ch[u][i]]=ch[fail[u]][i];
} else {
ch[u][i]=ch[fail[u]][i];
}
}
}
}

void find() {
int len=strlen(a);
int j=0;
for(int i=0; i<len; i++) {
int x=a[i]-'a'+1;
j=ch[j][x];
for(int k=j; k; k=fail[k]) sum[k]++;
}
}

void readin() {
for(int i=1; i<=n; i++) {
scanf("%s",lst[i]);
int y=strlen(lst[i]);
insert(lst[i],y,i);
}
make_fail();
scanf("%s",a);
}

void print() {
int ans=0;
for(int i=1; i<=m; i++) {
if(val[i]) ans=max(ans,sum[i]);
}
printf("%d\n",ans);
for(int i=1; i<=n; i++) {
if(sum[mp[i]]==ans) {
printf("%s\n",lst[i]);
}
}
}
};

AC ac;

int main() {
while(~scanf("%d",&n)&&n) {
ac.clr();
ac.readin();
ac.find();
ac.print();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  字符串 ac自动机