题目 https://cn.vjudge.net/problem/HDU-2896
记录出现子串的AC自动机
#include <bits/stdc++.h>
using namespace std;
const int MAX = 60000+100;
const int N = 10000+100;
const int SIGMA_SIZE = 128;
int ch[MAX][SIGMA_SIZE];
int val[MAX],last[MAX],f[MAX],sz;
int ANS;
int vis[550],flag;
void init()
{
sz = 1;
memset(ch, 0, sizeof(ch));
memset(val, 0, sizeof(val));
memset(f, 0, sizeof(f));
memset(last, 0, sizeof(last));
}
int idx(char c)
{
return c - ' ';
}
void add(int u)
{
while(u){
vis[val[u]]++;
// cout<<u<<" "<<val[u]<<endl;
u = last[u];
flag = 1;
}
}
void creat(char *s,int id)
{
int u = 0,len = strlen(s);
for(int i = 0; i < len; i++)
{
int c = idx(s[i]);
if(!ch[u][c]) ch[u][c] = sz++;
u = ch[u][c];
}
// cout<<u<<" "<<id<<endl;
val[u] = id;
}
void get_fail()
{
queue<int> q;
for(int i = 0; i < SIGMA_SIZE; i++)
{
if(ch[0][i]) q.push(ch[0][i]);
}
while(!q.empty())
{
int r = q.front();
q.pop();
for(int c = 0;c < SIGMA_SIZE; c++)
{
int u = ch[r][c];
if(!u){
ch[r][c] = ch[f[r]][c];
continue;
}
q.push(u);
int v = f[r];
while(v && ch[v][c] == 0) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
}
void find(char *T)
{
int len = strlen(T),j = 0;
for(int i = 0;i < len; i++)
{
char c = idx(T[i]);
j = ch[j][c];
if(val[j]) add(j);
}
}
char str[N];
int qwe[550];
int main()
{
init();
int n;
scanf("%d", &n);
for(int i = 1;i <= n;i++)
{
scanf("%s", str);
creat(str,i);
}
get_fail();
int m;
scanf("%d", &m);
int sum = 0;
for(int k = 1;k <= m;k++)
{
scanf("%s",&str);
flag = 0;
memset(vis,0,sizeof(vis));
find(str);
if(flag)
{
printf("web %d:",k);
for(int i = 1;i <= n;i++)
{
if(vis[i])
printf(" %d",i);
}
printf("\n");
sum++;
}
}
printf("total: %d\n",sum);
return 0;
}