题目地址:HDU 2896
AC自动机模板题。
记录每个终止节点的ID。然后在自动机里找就行了。
代码如下:
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
#include <string>
#include <time.h>
using namespace std;
#define LL long long
#define pi acos(-1.0)
#pragma comment(linker, "/STACK:1024000000")
const int mod=9901;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=1000000+300;
char s[20000];
struct Trie
{
int next[100010][130], fail[100010], id[100010], ha[600], tot[5];
int root, L;
int newnode()
{
for(int i=0;i<128;i++){
next[L][i]=-1;
}
id[L++]=0;
return L-1;
}
void init()
{
L=0;
root=newnode();
}
void Insert(char s[], int f)
{
int len=strlen(s);
int now=root;
for(int i=0;i<len;i++){
if(next[now][s[i]]==-1) next[now][s[i]]=newnode();
now=next[now][s[i]];
}
id[now]=f;
}
void Build()
{
queue<int>q;
fail[root]=root;
for(int i=0;i<128;i++){
int v=next[root][i];
if(v==-1) next[root][i]=root;
else {
fail[v]=root;
q.push(v);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<128;i++){
int v=next[u][i];
if(v==-1){
next[u][i]=next[fail[u]][i];
}
else{
fail[v]=next[fail[u]][i];
q.push(v);
}
}
}
}
int Query(char s[], int f)
{
memset(ha,0,sizeof(ha));
int ans=0, now=root;
int len=strlen(s);
for(int i=0;i<len;i++){
now=next[now][s[i]];
int tmp=now;
while(tmp!=root){
if(id[tmp]){
if(!ha[id[tmp]]){
tot[ans++]=id[tmp];
ha[id[tmp]]=1;
}
}
tmp=fail[tmp];
}
}
if(ans){
printf("web %d:",f);
sort(tot,tot+ans);
for(int i=0;i<ans;i++){
printf(" %d",tot[i]);
}
puts("");
}
if(!ans) return 0;
return 1;
}
}ac;
int main()
{
int n, m, i, sum;
while(scanf("%d",&n)!=EOF){
ac.init();
for(i=1;i<=n;i++){
scanf("%s",s);
ac.Insert(s,i);
}
ac.Build();
sum=0;
scanf("%d",&m);
for(i=1;i<=m;i++) {
scanf("%s",s);
sum+=ac.Query(s,i);
}
printf("total: %d\n",sum);
}
return 0;
}