题目 https://cn.vjudge.net/problem/HDU-3065
思路
统计出现次数的AC自动机
#include <bits/stdc++.h>
using namespace std;
const int MAX = 50000+100;
const int N = 2000000+100;
const int SIGMA_SIZE = 128;
int ch[MAX][SIGMA_SIZE];
int val[MAX],last[MAX],f[MAX],sz;
int ANS;
int vis[1550],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];
char s[1100][55];
int qwe[550];
int main()
{
int n;
while(scanf("%d",&n) != EOF){
init();
for(int i = 1; i <= n; i++)
{
scanf("%s", s[i]);
creat(s[i],i);
}
get_fail();
scanf("%s",&str);
memset(vis,0,sizeof(vis));
find(str);
for(int i = 1;i<=n;i++)
{
if(vis[i])
printf("%s: %d\n",s[i],vis[i]);
}
}
return 0;
}