您的位置:首页 > 其它

HDU2222 - Keywords Search - AC自动机

2017-08-18 19:14 363 查看

Keywords Search

题目链接

分类
data structures
strings


1.题意概述

给你N(N <= 10000)个模式串和一个待匹配串,现在问你待匹配串中出现过几种模式串?

2.解题思路

裸的AC自动机,因为问的是出现过几次,所以标记策略是每一类的最后一个位置置1,
Query
时候访问过一个种类就注意置0!

3.AC代码

class Trie {
public:
#define tot_len 500010
#define tot_ch 26
#define CUR (s[i] - 'a')
int next[tot_len][tot_ch], fail[tot_len], end[tot_len];
int root, L;

int Newnode() {
rep(i, 0, tot_ch) next[L][i] = -1;
end[L++] = 0;
return L - 1;
}

void Init() {
L = 0;
root = Newnode();
}

void Insert(char *s, int val) {
int len = strlen(s);
int now = root;
rep(i, 0, len) {
if (next[now][CUR] == -1)
next[now][CUR] = Newnode();
now = next[now][CUR];
}
end[now] += val;
}

void Build() {
queue<int> q;
fail[root] = root;
rep(i, 0, tot_ch) {
if (next[root][i] == -1)
next[root][i] = root;
else {
fail[next[root][i]] = root;
q.push(next[root][i]);
}
}
while (!q.empty()) {
int now = q.front();
q.pop();
rep(i, 0, tot_ch) {
if (next[now][i] == -1)
next[now][i] = next[fail[now]][i];
else {
fail[next[now][i]] = next[fail[now]][i];
q.push(next[now][i]);
}
}
}
}

int Query(char *s) {
int len = strlen(s);
int now = root, ans = 0;
rep(i, 0, len) {
now = next[now][CUR];
for (int j = now; j != root && end[j]; j = fail[j]) {
ans += end[j];
end[j] = 0;
}
}
return ans;
}
#undef CUR
#undef tot_ch
#undef tot_len
} AC;
char ch[maxn], key[51];
inline void solve() {
int t, n;
scanf("%d", &t);
while (t--) {
AC.Init();
scanf("%d", &n);
rep(i, 0, n) {
scanf("%s", key);
AC.Insert(key, 1);
}
AC.Build();
scanf("%s", ch);
printf("%d\n", AC.Query(ch));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu acm