题目传送门
(话说最近不知道为啥hdu改名了???所以之前的网址都无效了???)
题意解析:题目就是给了n个模式串,一个匹配串,问你每个模式串在匹配串中出现的次数。
都说了最近在做AC自动机的模板题,而且也挺明显的。
还有因为这其实是第一题我做的AC自动机,所以去网上找了模板。
直接上代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define Clear(a,x) memset(a,x,sizeof(a))
#define ll long long
#define INF 2000000000
#define eps 1e-8
using namespace std;
int read(){
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9') f=ch=='-'?-1:f,ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxnode=50005,maxsize=128;
int cnt[1005];
struct AC{
int ch[maxnode][maxsize];
int val[maxnode];
int f[maxnode];
int suffix[maxnode];
int Cnt;
inline void init(){
Cnt=0;
Clear(ch[0],0);
val[0]=f[0]=suffix[0]=0;
}
inline void insert(char *s,int v){
int len=strlen(s),u=0;
rep(i,0,len-1){
int id=s[i];
if (!ch[u][id]){
ch[u][id]=++Cnt;
Clear(ch[Cnt],0);
val[Cnt]=0;
}
u=ch[u][id];
}
val[u]=v;
}
inline void print(int i){
if (val[i]){
cnt[val[i]]++;
print(suffix[i]);
}
}
inline void find(char *s){
int len=strlen(s),u=0;
rep(i,0,len-1){
int id=s[i];
while (u&&!ch[u][id]) u=f[u];
u=ch[u][id];
if (val[u]) print(u);
else if (suffix[u]) print(suffix[u]);
}
}
inline void getfail(){
queue<int> q;
f[0]=0;
rep(i,0,maxsize-1){
int u=ch[0][i];
if (u){
suffix[u]=f[u]=0;
q.push(u);
}
}
while (!q.empty()){
int r=q.front();
q.pop();
rep(i,0,maxsize-1){
int u=ch[r][i];
if (!u) continue;
q.push(u);
int v=f[r];
while (v&&!ch[v][i]) v=f[v];
f[u]=ch[v][i];
suffix[u]=val[f[u]]?f[u]:suffix[f[u]];
}
}
}
}ac;
int n;
char s[1005][60];
char text[2000005];
int main(){
while (~scanf("%d",&n)&&n){
ac.init();
Clear(cnt,0);
rep(i,1,n){
scanf("%s",s[i]);
ac.insert(s[i],i);
}
ac.getfail();
scanf("%s",text);
ac.find(text);
rep(i,1,n)
if (cnt[i])
printf("%s: %d\n",s[i],cnt[i]);
}
return 0;
}
结构体大法好