您的位置:首页 > 其它

HDU2222 Keywords Search 【AC自动机模板题】

2017-08-09 20:50 465 查看
链接

AC自动机一直搜即可

注意每次+end[i]后,需要把end[i]=0,避免重复计算

#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))

using namespace std;

struct Trie{
const static int maxn=5e5+5;
const static int BASE='a';
const static int N = 26;
int next[maxn]
,end[maxn];
int root,L;

int newNode(){
MEM(next[L],-1);
end[L++]=0;
return L-1;
}
void init(){
L=0;
root=newNode();
}
void insert(char buf[]){
int now=root;
for(int i=0;buf[i];++i){
int j=buf[i]-BASE;
if(next[now][j]==-1){
next[now][j]=newNode();
}
now=next[now][j];
}
end[now]++;
}
//ac自动机
int fail[maxn];
void build(){
queue<int>que;
fail[root]=root;
for(int i=0;i<N;++i){
if(next[root][i]==-1){
next[root][i]=root;
}
else{
fail[next[root][i]]=root;
que.push(next[root][i]);
}
}
while(!que.empty()){
int now=que.front();
que.pop();
for(int i=0;i<N;++i){
if(next[now][i]==-1){
next[now][i]=next[fail[now]][i];
}
else{
fail[next[now][i]]=next[fail[now]][i];
que.push(next[now][i]);
}
}
}
}

ll getNum(int now){
ll ans=0;
while(now!=root){
ans+=end[now];
end[now]=0;
now=fail[now];
}
return ans;
}

ll query(char buf[]){
int now=root;
ll ans=0;
for(int i=0;buf[i];++i){
now=next[now][buf[i]-BASE];
ans+=getNum(now);
}
return ans;
}
}trie;

const int N = 1000000 +5;
char buf
;

int main()
{
//freopen("/home/lu/code/r.txt","r",stdin);
//freopen("/home/lu/code/w.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
trie.init();
while(n--){
sc
4000
anf("%s",buf);
trie.insert(buf);
}
trie.build();
scanf("%s",buf);
printf("%lld\n",trie.query(buf));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU AC自动机