传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=2222
蒟蒻AC自动机第一题,刷了个模板题……
注意模板可能有相同的的,map判重最后乘上个数
还有就是原来hud的g++版本数3.4.1的,……必须include<string>才能用string
Code:
#include<queue>
#include<map>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
map<string,int>M;
struct AhoCorasickAutomata{
int ch[250100][26];
int fail[250100];
int val[250100];
int last[250100];
int cnt[250100];
int sz;
void init(){
sz=1;
memset(ch,0,sizeof(ch));
memset(cnt,0,sizeof(cnt));
memset(fail,0,sizeof(fail));
memset(val,0,sizeof(val));
memset(last,0,sizeof(last));
}
int idx(char c){
return c-'a';
}
void insert(char *s,int v){
int u=0,n=strlen(s);
for(int i=0;i<n;i++){
int c=idx(s[i]);
if(!ch[u][c]){
memset(ch[sz],0,sizeof(sz));
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
void print(int j){
if(j){
cnt[val[j]]=1;
print(last[j]);
}
}
void find(char *T){
int n=strlen(T);
int ans=0,j=0;
for(int i=0;i<n;i++){
int c=idx(T[i]);
j=ch[j][c];
if(val[j])print(j);
else if(last[j])print(last[j]);
}
}
void get_fail(){
queue<int>q;
fail[0]=0;
for(int c=0;c<26;c++){
int u=ch[0][c];
if(u){
fail[u]=0;
q.push(u);
last[u]=0;
}
}
while(!q.empty()){
int r=q.front();q.pop();
for(int c=0;c<26;c++){
int u=ch[r][c];
if(!u){ch[r][c]=ch[fail[r]][c];continue;}
q.push(u);
int v=fail[r];
while(v&&!ch[v][c])v=fail[v];
fail[u]=ch[v][c];
last[u]=val[fail[u]]?fail[u]:last[fail[u]];
}
}
}
}ac;
char s[1000001];
char t[10001][51];
int T;
int sum[10001];
int vis[10001];
int main(){
scanf("%d",&T);
int n;
while(T--){
ac.init();M.clear();
memset(sum,0,sizeof(sum));
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s",t[i]);
for(int i=1;i<=n;i++){
if(!M.count(string(t[i]))){
vis[i]=1;
sum[i]=1;
M[string(t[i])]=i;
}else
sum[M[string(t[i])]]++;
}
for(int i=1;i<=n;i++)if(vis[i])
ac.insert(t[i],i);
ac.get_fail();
scanf("%s",s);
int ans=0;
ac.find(s);
for(int i=1;i<=n;i++)
if(vis[i])
ans+=ac.cnt[i]*sum[i];
printf("%d\n",ans);
}
return 0;
}