[HDOJ2846]Repository(字典树)

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

题意:求一堆串中有多少个以0开始的子串包含目标串。

可以把所有的串符合要求的子串放入字典树统计。这时候会有一个问题,那就是adddd这样的单词:样例中已经说明了,这样的单词明显是只算一次的。所以可以在字典树中打标记,每一个节点最后更新的时候的字符串是哪个。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef struct Node {
 5     Node* next[26];
 6     int cnt, id;
 7 }Node;
 8 int n, q, ncnt;
 9 char tmp[22];
10 Node memory[350000];
11 Node* rt;
12 
13 void insert(Node* rt, char* s, int id) {
14     Node* p = rt;
15     for(int i = 0; s[i]; i++) {
16         int x = s[i] - 'a';
17         if(p->next[x] == NULL) {
18             p->next[x] = &memory[ncnt++];
19             p->next[x]->id = -1;
20         }
21         p = p->next[x];
22         if(id != p->id) {
23             p->cnt++;
24             p->id = id;
25         }
26     }
27 }
28 
29 int query(Node* rt, char* s) {
30     Node* p = rt;
31     for(int i = 0; s[i]; i++) {
32         int x = s[i] - 'a';
33         if(p->next[x] == NULL) return 0;
34         p = p->next[x];
35     }
36     return p->cnt;
37 }
38 
39 int main() {
40     // freopen("in", "r", stdin);
41     while(~scanf("%d", &n)) {
42         ncnt = 0;
43         memset(memory, 0, sizeof(memory));
44         rt = &memory[ncnt++];
45         memset(rt->next, 0, sizeof(rt->next));
46         for(int i = 0; i < n; i++) {
47             scanf("%s", tmp);
48             for(int j = 0; tmp[j]; j++) {
49                 insert(rt, tmp+j, i);
50             }
51         }
52         scanf("%d", &q);
53         while(q--) {
54             scanf("%s", tmp);
55             printf("%d
", query(rt, tmp));
56         }
57     }
58     return 0;
59 }
原文地址:https://www.cnblogs.com/kirai/p/5942734.html