您的位置:首页 > 其它

HDU 2222 - Keywords Search

2017-08-09 23:22 246 查看
试个模板- -

/*
HDU 2222 - Keywords Search [ AC自动机 ]
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
const int SIZE = 26;
struct Trie {
int ch
[SIZE];
int f
, last
, cnt
, val
;
int tot, ans;
void init() {
tot = 0;
memset(ch, 0, sizeof(ch));
memset(val, 0, sizeof(val));
}
int ord(char c) {
return c-'a';
}
void insert(char* s) {
int now = 0, n = strlen(s);
for (int i = 0; i < n; i++) {
int t = ord(s[i]);
if (!ch[now][t]) ch[now][t] = ++tot;
now = ch[now][t];
}
val[now]++;
}
void getFail() {
queue<int> Q;
f[0] = 0;
for (int t = 0; t < SIZE; t++) {
int now = ch[0][t];
if (now) {
f[now] = last[now] = 0;
Q.push(now);
}
}
while (!Q.empty()) {
int k = Q.front(); Q.pop();
for (int t = 0; t < SIZE; t++) {
int now = ch[k][t];
if(!now) continue;
Q.push(now);
int nxt = f[k];
while (nxt && !ch[nxt][t]) nxt=f[nxt];
f[now] = ch[nxt][t];
last[now] = val[f[now]] ? f[now] : last[f[now]];
}
}
}
void add(int now) {
for (; now; now = last[now]) ans += val[now], val[now] = 0;
}
void Find(char* s) {
int now = 0, n = strlen(s);
ans = 0;
for (int i = 0; i < n; i++) {
int t = ord(s[i]);
while (now && !ch[now][t]) now = f[now];
now = ch[now][t];
if (val[now]) add(now);
else if (last[now]) add(last[now]);
}
}
}ac;
char s[1000005];
int main()
{
int t; scanf("%d", &t);
while (t--)
{
ac.init();
int n; scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%s", s);
ac.insert(s);
}
ac.getFail();
scanf("%s", s);
ac.Find(s);
printf("%d\n", ac.ans);
}
}


 

#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
struct Tire {
int ch
[26], f
, tot;
int val
, vis
;
void init() {
tot = 0;
memset(ch, 0, sizeof(ch));
memset(f, 0, sizeof(f));
memset(val, 0, sizeof(val));
}
int ord(char c) {
return c - 'a';
}
void insert(char* s) {
int now = 0, n = strlen(s);
for (int i = 0; i < n; i++)
{
int t = ord(s[i]);
if (!ch[now][t]) ch[now][t] = ++tot;
now = ch[now][t];
}
val[now]++;
}
void buildFail()
{
queue<int> Q;
f[0] = 0;
for (int t = 0; t < 26; t++) {
int now = ch[0][t];
if (now) {
Q.push(now);
f[now] = 0;
}
}
while (!Q.empty()) {
int now = Q.front(); Q.pop();
for (int t = 0; t < 26; t++) {
int v = ch[now][t];
if (!v) {ch[now][t] = ch[f[now]][t]; continue; }
Q.push(v);
int nxt = f[now];
while (nxt && !ch[nxt][t]) nxt = f[nxt];
f[v] = ch[nxt][t];
}
}
}
int Find(char *s) {
int ans = 0;
int n = strlen(s), now = 0;
memset(vis, 0, sizeof(vis));
for (int i = 0; i < n; i++)
{
int t = ord(s[i]);
//  while (now && !ch[now][t]) now = f[now];
now = ch[now][t];
int tmp = now;
while (tmp)
{
if (vis[tmp]) break;
vis[tmp] = 1;
ans += val[tmp];
val[tmp] = 0;
tmp = f[tmp];
}
}
return ans;
}
}ac;
char s[1000005];
int t, n;
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
ac.init();
while (n--)
{
scanf("%s", s);
ac.insert(s);
}
ac.buildFail();
scanf("%s", s);
printf("%d\n", ac.Find(s));
}
}


  

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: