您的位置:首页 > 其它

[HDOJ3065]病毒侵袭持续中

2015-08-27 21:02 281 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065

题都懒得粘了…好的AC自动机模版真难找。也许是自己太水

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <climits>
#include <cmath>

using namespace std;

int n;
inline int GetId(char c) {
return c - 'A';
}

typedef struct vir {
string name;
int freq;
}vir;

typedef class Node {
public:
Node *chd[26];
Node *fail;
int id;

Node(){
memset(chd, 0, sizeof(chd));
fail = NULL;
id = -1;
}
}Node;

class AC_Automation {
public:
Node *root;
queue <Node*> q;
vir v[1005];

AC_Automation() {
root = new Node;
while(!q.empty()) {
q.pop();
}
for(int i = 0; i < n; i++)
v[i].freq = 0;
}
void insert(string s, int th) {
Node *cur = root;
int len = s.length();
for(int i = 0; i < len; i++) {
int index = GetId(s[i]);
if(!cur->chd[index]) {
cur->chd[index] = new Node;
}
cur = cur->chd[index];
}
cur->id = th;
v.name = s;
}
void BuildAC() {
Node *cur,*tmp;
q.push(root);
while(!q.empty()) {
cur = q.front();
q.pop();
for(int i = 0; i < 26; i++) {
if(cur->chd[i]) {
if(cur == root) {
cur->chd[i]->fail = root;
}
else {
tmp = cur->fail;
while(tmp->fail && !tmp->chd[i]) {
tmp = tmp->fail;
}
if(tmp->chd[i]) {
cur->chd[i]->fail = tmp->chd[i];
}
else {
cur->chd[i]->fail = root;
}
}
q.push(cur->chd[i]);
}
}
}
}
void query(string s) {
Node *cur = root,*tmp;
int len = s.length();
for(int i = 0; i < len; i++) {
int index = GetId(s[i]);
if(index < 0 || index >= 26) {
cur = root;
continue;
}
if(cur->chd[index]) {
cur = cur->chd[index];
}
else {
while(cur && !cur->chd[index]) {
cur =  cur->fail;
}
if(!cur) {
cur = root;
}
if(cur->chd[index]) {
cur = cur->chd[index];
}
}
tmp = cur;
while(tmp->fail) {
if(tmp->id > -1) {
v[tmp->id].freq++;
}
tmp = tmp->fail;

}
}
}
};
char pat[52], tar[2000005];

int main() {
// freopen("in", "r", stdin);
while(scanf("%d", &n) == 1) {
AC_Automation ac;
getchar();
for(int i = 0; i < n; i++) {
gets(pat);
ac.insert(pat,i);
}
ac.BuildAC();
gets(tar);
ac.query(tar);
for(int i = 0; i < n; i++) {
if(ac.v[i].freq) {
cout << ac.v[i].name << ": " << ac.v[i].freq << endl;
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: