标签:sizeof input 匹配 arc problem null ems pre amp
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 57724 Accepted Submission(s): 18954
给出一些A串,和一个B串,询问有多少个A串是B的子串。
先对所有A串构造Trie树,然后建成AC自动机。这样用B串在自动机中做匹配时,每每匹配到一个结点t,在这个结点以及t->fail,t->fail->fail...等结点上结束的A串都是在B串中匹配上的。因此应当从t一直顺fail指针走到root,同时注意不要重复统计相同的A串。
1 #include <bits/stdc++.h> 2 3 struct node { 4 int count; 5 node *fail; 6 node *next[26]; 7 node(void) { 8 memset(this, 0, sizeof(node)); 9 } 10 }*root; 11 12 inline void insert(char *s) { 13 node *t = root; 14 for ( ; *s; ++s) { 15 if (t->next[*s - ‘a‘] == NULL) 16 t->next[*s - ‘a‘] = new node; 17 t = t->next[*s - ‘a‘]; 18 } 19 ++t->count; 20 } 21 22 inline void build(void) { 23 root->fail = root; 24 std::queue<node *> q; 25 for (int i = 0; i < 26; ++i) 26 if (root->next[i]) { 27 root->next[i]->fail = root; 28 q.push(root->next[i]); 29 } 30 while (!q.empty()) { 31 node *t = q.front(); q.pop(); 32 for (int i = 0; i < 26; ++i) 33 if (t->next[i]) { 34 node *p = t->fail; 35 while (p != root && !p->next[i]) 36 p = p->fail; 37 if (p->next[i]) 38 t->next[i]->fail = p->next[i]; 39 else 40 t->next[i]->fail = root; 41 q.push(t->next[i]); 42 } 43 } 44 } 45 46 inline int count(char *s) { 47 int ans = 0; 48 node *t = root; 49 for ( ; *s; ++s) { 50 while (t != root && !t->next[*s - ‘a‘]) 51 t = t->fail; 52 if (t->next[*s - ‘a‘]) 53 t = t->next[*s - ‘a‘]; 54 for (node *p = t; p != root && p->count != -1; p = p->fail) 55 ans += p->count, p->count = -1; 56 } 57 return ans; 58 } 59 60 signed main(void) { 61 int cas, n; scanf("%d", &cas); 62 for (char s[1000005]; cas--; ) { 63 root = new node; 64 scanf("%d", &n); 65 while (n--) { 66 scanf("%s", s); 67 insert(s); 68 } 69 build(); 70 scanf("%s", s); 71 printf("%d\n", count(s)); 72 } 73 }
@Author: YouSiki
标签:sizeof input 匹配 arc problem null ems pre amp
原文地址:http://www.cnblogs.com/yousiki/p/6177852.html