来源:HDU2896
注意中间需要判重,本来准备开一个vis数组的,但是后来发现MLE了,所以只好STL判重,注意在使用中实际上en数组赋值为了ID,从而减少了数组的开销,这是个灵活的地方
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define STOP getchar();
using namespace std;
string str;
int n,m;
const int ALTN = 129;
const int MAXN = 2000005;
struct AC_machine{
int nxt[MAXN][ALTN];
int fail[MAXN];
int en[MAXN];
int root,L;
int virus[1000];
int cnt;
int ID;
//L是ID分配器
int newnode(){
for(int i=0;i<ALTN;i++)
nxt[L][i]=-1;
en[L++]=0;
return L-1;
}
void ini(){
L=0;
ID=0;
cnt=0;
root = newnode();
}
void ini_v(){
cnt=0;
memset(virus,0,sizeof(virus));
}
void insert_in(string str){
int len = str.length();
int now = root;
for(int i=0;i<len;i++){
if(nxt[now][str[i]]==-1){
nxt[now][str[i]]=newnode();
}
now = nxt[now][str[i]];
}
en[now]=++ID;
}
void build(){
queue<int>Q;
fail[root]=root;
for(int i=0;i<ALTN;i++){
if(nxt[root][i]==-1) nxt[root][i]=root;
else {
fail[nxt[root][i]]=root;
Q.push(nxt[root][i]);
}
}
while(!Q.empty()){
int temp = Q.front();
Q.pop();
for(int i=0;i<ALTN;i++){
if(nxt[temp][i]==-1) nxt[temp][i] = nxt[fail[temp]][i];
else{
fail[nxt[temp][i]] = nxt[fail[temp]][i];
Q.push(nxt[temp][i]);
}
}
}
}
int query(string str,int nc){
int res=0;
int len = str.length();
int now=root;
for(int i=0;i<len;i++){
now = nxt[now][str[i]];
int temp = now;
while(temp!=root){
if(en[temp]) {
virus[cnt++]=en[temp];
res++;
}
temp = fail[temp];
}
}
if(!res) return 0;
cout<<"web "<<nc<<":";
sort(virus,virus+cnt);
cnt = unique(virus,virus+cnt)-virus;
for(int i=0;i<cnt;i++)
cout<<" "<<virus[i];
cout<<endl;
return 1;
}
}ac;
int main(){
while(scanf("%d",&n)!=EOF){
getchar();
ac.ini();
for(int i=0;i<n;i++){
getline(cin,str);
ac.insert_in(str);
}
// cout<<"successful insert!"<<endl;
ac.build();
scanf("%d",&m);
getchar();
int ans=0;
for(int i=1;i<=m;i++){
getline(cin,str);
ac.ini_v();
if(ac.query(str,i)) ans++;
}
cout<<"total: "<<ans<<endl;
}
return 0;
}
/*
3
aaa
bbb
ccc
4
aaabbbcccaaa
bbbaaccbbb
aaabbbccc
bbaacc
*/