1. 程式人生 > >HDU 3065 病毒侵襲持續中(AC自動機)

HDU 3065 病毒侵襲持續中(AC自動機)

open truct printf ans sin print color char continue

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自動機)