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

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

时间:2017-08-26 19:50:59      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:ref   printf   ios   eof   names   turn   tac   char   tmp   

http://acm.hdu.edu.cn/showproblem.php?pid=3065

题意:
求每个模式串出现的次数。

 

思路:

不难,把模板修改一下即可。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<vector>
  6 #include<stack>
  7 #include<queue>
  8 #include<cmath>
  9 #include<map>
 10 #include<set>
 11 using namespace std;
 12 typedef long long ll;
 13 const int INF = 0x3f3f3f3f;
 14 const int maxn=10000+5;
 15 
 16 int n;
 17 int num;
 18 char str[1005][55];
 19 char s[2000005];
 20 int ans[1005];
 21 
 22 struct Trie
 23 {
 24     int son[30];
 25     int cnt;
 26     int id;
 27     int fail;
 28 }t[1000*50+5];
 29 
 30 void init(int x)
 31 {
 32     t[x].cnt=t[x].fail=0;
 33     memset(t[x].son,0,sizeof(t[x].son));
 34 }
 35 
 36 void trie(char *s, int id)
 37 {
 38     int n=strlen(s);
 39     int x=0;
 40     for(int i=0;i<n;i++)
 41     {
 42         int c=s[i]-A+1;
 43         if(!t[x].son[c])
 44         {
 45             num++;
 46             init(num);
 47             t[x].son[c]=num;
 48         }
 49         x=t[x].son[c];
 50     }
 51     t[x].cnt++;
 52     t[x].id=id;
 53 }
 54 
 55 void buildAC()
 56 {
 57     queue<int> Q;
 58     for(int i=1;i<=26;i++)  if(t[0].son[i])  Q.push(t[0].son[i]);
 59     while(!Q.empty())
 60     {
 61         int x=Q.front(); Q.pop();
 62         int fail=t[x].fail;
 63         for(int i=1;i<=26;i++)
 64         {
 65             int y=t[x].son[i];
 66             if(y)
 67             {
 68                 t[y].fail=t[fail].son[i];
 69                 Q.push(y);
 70             }
 71             else t[x].son[i]=t[fail].son[i];
 72         }
 73     }
 74 }
 75 
 76 void query(char *s)
 77 {
 78     int n=strlen(s);
 79     int x=0;
 80     for(int i=0;i<n;i++)
 81     {
 82         if(!(s[i]>=A && s[i]<=Z))  {x=0;continue;}
 83         int c=s[i]-A+1;
 84         while(x && !t[x].son[c])  x=t[x].fail;
 85         x=t[x].son[c];
 86         int tmp=x;
 87         while(tmp)  //回到0就不需要再计数了
 88         {
 89             if(t[tmp].cnt!=0) ans[t[tmp].id]++;
 90             tmp=t[tmp].fail;
 91         }
 92     }
 93 }
 94 
 95 int main()
 96 {
 97     //freopen("in.txt","r",stdin);
 98     while(~scanf("%d",&n))
 99     {
100         num=0;
101         init(0);
102         scanf("%d",&n);
103         for(int i=1;i<=n;i++)
104         {
105             ans[i]=0;
106             scanf("%s",str[i]);
107             trie(str[i],i);
108         }
109         buildAC();
110         scanf("%s",s);
111         query(s);
112         for(int i=1;i<=n;i++)
113         {
114             if(ans[i]) printf("%s: %d\n",str[i],ans[i]);
115         }
116     }
117     return 0;
118 }

 

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

标签:ref   printf   ios   eof   names   turn   tac   char   tmp   

原文地址:http://www.cnblogs.com/zyb993963526/p/7435993.html

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