您的位置:首页 > 其它

HDU 2222 Keywords Search [AC自动机]

2015-05-06 20:38 357 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2222

题意:给一堆模式串和一个文本串,问有多少个模式串在文本串中出现过。

AC自动机,在统计答案的时候记得将end清零就好

#include<queue>
#include<cassert>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;
#define rep(i,f,t) for(int i = (f), _end = (t); i <= _end; ++i)
#define dep(i,f,t) for(int i = (f), _end = (t); i >= _end; --i)
#define clr(c,x) memset(c,x,sizeof(c));
#define debug(x) cout<<"debug  "<<x<<endl;
const int INF = 0x3f3f3f3f;
typedef long long int64;

inline int RD(){ int res; scanf("%d",&res); return res; }

#define Rush for(int casn = RD(), cas = 1; cas <= casn; ++cas)

//*******************************************************************************

const int maxn = 10005;
struct Trie{
int next[maxn*50][26];
int fail[maxn*50];
int end[maxn*50];
int sz;
void init(){ sz = 0; clr(next[0],0); }
int newnode(){
++sz;
clr(next[sz],0);
fail[sz] = end[sz] = 0;
return sz;
}

void insert(char *s){
int u = 0;
while(*s){
int nid = *s++ - 'a';
if(!next[u][nid]){
next[u][nid] = newnode();
}
u = next[u][nid];
}
++end[u];
}

void build(){
queue<int> Q;
int u = 0;
rep(c,0,25){
if(next[0][c]){
Q.push(next[0][c]);
}
}
while(!Q.empty()){
u = Q.front();
Q.pop();
int fu = fail[u];
rep(c,0,25){
int v = next[u][c];
if(v){
Q.push(v);
fail[v] = next[fu][c];
}else{
next[u][c] = next[fu][c];
}
}
}
}

int query(char *s){
int u = 0;
int ans = 0;
while(*s){
int nid = *s++ - 'a';
u = next[u][nid];
int k = u;
while(k){
if(end[k]){
ans += end[k];
end[k] = 0;
}
k = fail[k];
}
}
return ans;
}
}ac;
char str[1000009];
int main(){
Rush{
ac.init();
int n;
scanf("%d",&n);
while(n--){
scanf("%s",str);
ac.insert(str);
}
ac.build();
scanf("%s",str);
printf("%d\n",ac.query(str));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: