您的位置:首页 > 其它

HDU2896 - 病毒入侵 - AC自动机

2017-08-18 19:19 197 查看

病毒侵袭

题目链接

分类
data structures
strings


1.题意概述

给你N(1<=N<=500)个模式串,M(1<=M<=1000)个待匹配串,查询这M个串每个串中模式串出现过哪几个,和总的出现次数。

2.解题思路

也是裸的AC自动机,因为是有查询几次,为了方便输出,我们插入同时维护记录一下插入的每个模式串的id和次数。

3.AC代码

class Trie {
public:
#define tot_len 100010
#define tot_ch 130
#define CUR s[i]
int next[tot_len][tot_ch], fail[tot_len], end[tot_len];
bool used[510];
int root, L;

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

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

void Insert(char *s, int id) {
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] = id;
}

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]);
}
}
}
}

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