HDU 2846 Repository(字典树)
Posted new-ljx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2846 Repository(字典树)相关的知识,希望对你有一定的参考价值。
嗯...
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2846
这与裸的字典树略有差别:
因为题目要求有n个字符串,m个询问 问字符串在n个字符串中出现过多少次,
即为一个字串的问题,所以我们把一个字符串拆开分别建树。
eg:
abcd 中有a,b,c,d,abcd,bcd,cd,bc,abc...
我们可以将abcd拆成abcd bcd cd d 分别建树
注意:
abab会导致重复,所以用flag标记:若此编号不同于所给编号(此后缀在本要查的字符串中没有)才加1,这样就避免了重复。
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 5 using namespace std; 6 7 int ch[500005][30]; 8 int flag[500005]; 9 int val[500005]; 10 int cnt = 1; 11 12 inline int ids(char c){ 13 return c - ‘a‘; 14 } 15 16 inline void build(char *s, int k){ 17 int u = 0; 18 int len = strlen(s); 19 for(int i = 0; i < len; i++){ 20 int id = ids(s[i]); 21 if(!ch[u][id]) ch[u][id] = cnt++; 22 u = ch[u][id]; 23 if(flag[u] != k){ 24 val[u]++; 25 flag[u] = k; 26 } 27 } 28 } 29 30 inline int query(char *s){ 31 int len = strlen(s); 32 int u = 0; 33 for(int i = 0; i < len; i++){ 34 int id = ids(s[i]); 35 if(!ch[u][id]) return 0; 36 u = ch[u][id]; 37 } 38 return val[u]; 39 } 40 41 int main(){ 42 int p, q; 43 char s[25]; 44 scanf("%d", &p); 45 memset(flag, -1, sizeof(flag)); 46 for(int i = 1; i <= p; i++){ 47 scanf("%s", s); 48 int len = strlen(s); 49 for(int j = 0; j < len; j++) 50 build(s + j, i); 51 } 52 scanf("%d", &q); 53 for(int i = 0; i < q; i++){ 54 scanf("%s", s); 55 printf("%d ", query(s)); 56 } 57 return 0; 58 }
以上是关于HDU 2846 Repository(字典树)的主要内容,如果未能解决你的问题,请参考以下文章