码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3065 病毒侵袭持续中(AC自动机)

时间:2015-06-18 09:33:11      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065

题意:有n个模式串,一个主串,求每个模式串在主串中出现的次数

思路:AC自动机水题,trie树中也要维护标号,再开一个num数组记录出现次数即可,扫描匹配时注意跳转fail指针和root节点。

code:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <string>
  4 #include <queue>
  5 using namespace std;
  6 const int KIND = 26;
  7 struct node
  8 {
  9     int id;
 10     node* fail;
 11     node* next[KIND];
 12     node ()
 13     {
 14         id = 0;
 15         fail = NULL;
 16         for (int i = 0; i < KIND; ++i) next[i] = NULL;
 17     }
 18 };
 19 node* root;
 20 int L;
 21 char str[1005][55];
 22 char text[2000005];
 23 int num[1005];
 24 
 25 void Insert(char str[])
 26 {
 27     node* temp = root;
 28     int len = strlen(str);
 29     for (int i = 0; i < len; ++i)
 30     {
 31         int curr = str[i] - A;
 32         if (temp->next[curr] == NULL)
 33             temp->next[curr] = new node();
 34         temp = temp->next[curr];
 35     }
 36     temp->id = ++L;
 37 }
 38 
 39 void Build()
 40 {
 41     queue<node*> Q;
 42     root->fail = root;
 43     for (int i = 0; i < KIND; ++i)
 44     {
 45         if (root->next[i] == NULL)
 46             root->next[i] = root->fail->next[i];
 47         else
 48         {
 49             root->next[i]->fail = root;
 50             Q.push(root->next[i]);
 51         }
 52     }
 53     while (!Q.empty())
 54     {
 55         node* temp = Q.front();
 56         Q.pop();
 57         for (int i = 0; i < KIND; ++i)
 58         {
 59             if (temp->next[i] == NULL)
 60                 temp->next[i] = temp->fail->next[i];
 61             else
 62             {
 63                 temp->next[i]->fail = temp->fail->next[i];
 64                 Q.push(temp->next[i]);
 65             }
 66         }
 67     }
 68 }
 69 
 70 void Query()
 71 {
 72     node* temp = root;
 73     int len = strlen(text);
 74     for (int i = 0; i < len; ++i)
 75     {
 76         if (text[i] < A || text[i] > Z)
 77         {
 78             temp = root;
 79             continue;
 80         }
 81         int curr = text[i] - A;
 82         while (temp->next[curr] == NULL && temp != root) temp = temp->fail;
 83         temp = temp->next[curr];
 84         if (temp == NULL) temp = root;
 85         node* x = temp;
 86         while (x != root)
 87         {
 88             if (x->id != 0) ++num[x->id];
 89             x = x->fail;
 90         }
 91     }
 92 }
 93 
 94 int main()
 95 {
 96     int n;
 97     while (scanf("%d", &n) != EOF)
 98     {
 99         L = 0;
100         root = new node();
101         for (int i = 1; i <= n; ++i)
102         {
103             scanf("%s", str[i]);
104             Insert(str[i]);
105         }
106         Build();
107         scanf("%s", text);
108         memset(num, 0, sizeof(num));
109         Query();
110         for (int i = 1; i <= n; ++i)
111         {
112             if (num[i] == 0) continue;
113             printf("%s: %d\n", str[i], num[i]);
114         }
115     }
116     return 0;
117 }

 

HDU 3065 病毒侵袭持续中(AC自动机)

标签:

原文地址:http://www.cnblogs.com/ykzou/p/4584928.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!