传..传送:http://acm.hdu.edu.cn/showproblem.php?pid=5687

Problem C

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2697    Accepted Submission(s): 743

Problem Description
度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:
  1、insert : 往神奇字典中插入一个单词
  2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
  3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串
 
Input
这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000),代表度熊对于字典的操作次数,接下来N行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。
 
Output
对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。
 
Sample Input
5
insert hello
insert hehe
search h
delete he
search hello
Sample Output
Yes
No
 
Source
 

解题思路:

输入查询都是字典树基本操作,这里的字典树的删除是一种标记删除而不是物理删除(非最后节点)。

但是这里的标记删除要注意的是不能直接取消标记或标记为 0 ,而是要根据要删除的字符串在字典中出现的次数,然后根据这个次数去更新路径上的点的标记。如果是删除字符的最后节点则进行物理删除。

例如说:字典里是 zzaizjja,zzaizjj,要删除 zzaizjja,如果单纯把路径 zzaizjja 上的节点都更新为0,则它的子串也 out 了,所以正确的更新是:路径上的点减去zzaizjja出现的次数。

AC Code:

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <cstring>
  6. #define INF 0x3f3f3f3f
  7. #define LL long long int
  8. #define Bits 26
  9. using namespace std;
  10. const int MAXN = ;
  11. int N;
  12. struct Trie
  13. {
  14. Trie *next[Bits];
  15. int flag;
  16. inline void init(){
  17. this->flag = ;
  18. for(int i = ; i < Bits; i++)
  19. this->next[i] = NULL;
  20. }
  21. };
  22. Trie *Root = (Trie *)malloc(sizeof(Trie));
  23. inline void DelTrie(Trie *t)
  24. {
  25. if(t == NULL) return;
  26. for(int i = ; i < Bits; i++){
  27. if(t->next[i]!=NULL) DelTrie(t->next[i]);
  28. }free(t);
  29. return;
  30. }
  31.  
  32. void Create_Trie(char *str, bool isDel)
  33. {
  34. int len = strlen(str);
  35. Trie *p = Root, *temp;
  36. int Delnum = ;
  37. for(int i = ; i < len; i++){
  38. int index = str[i]-'a';
  39. if(!isDel){
  40. if(p->next[index] == NULL){
  41. temp = (Trie *)malloc(sizeof(Trie));
  42. temp->init();
  43. p->next[index] = temp;
  44. p = p->next[index];
  45. }
  46. else{p->next[index]->flag+=; p=p->next[index];}
  47. }
  48. else{
  49. if(p->next[index] != NULL){
  50. Delnum = p->next[index]->flag;
  51. p = p->next[index];
  52. }else return;
  53. }
  54. }
  55. if(isDel){
  56. p = Root;
  57. for(int i = ; i < len; i++){
  58. int index = str[i]-'a';
  59. if(p->next[index] == NULL) return;
  60. if(i==len-){
  61. DelTrie(p->next[index]);
  62. p->next[index] = NULL;
  63. return;
  64. }
  65. p->next[index]->flag-=Delnum;
  66. p = p->next[index];
  67. }
  68. }
  69. }
  70.  
  71. bool Find_Trie(char *str)
  72. {
  73. int len = strlen(str);
  74. Trie *p = Root;
  75. for(int i = ; i < len; i++){
  76. int index = str[i]-'a';
  77. if(p->next[index] != NULL && p->next[index]->flag > )
  78. p=p->next[index];
  79. else return false;
  80. }return true;
  81. }
  82.  
  83. int main()
  84. {
  85. Root->init();
  86. scanf("%d", &N);
  87. char str[MAXN], command[];
  88. while(N--){
  89. scanf("%s", command);
  90. if(strcmp(command, "insert")==){
  91. scanf("%s", str);
  92. Create_Trie(str, false);
  93. }
  94. else if(strcmp(command, "delete")==){
  95. //puts("zjj");
  96. scanf("%s", str);
  97. Create_Trie(str, true);
  98. }
  99. else{
  100. scanf("%s", str);
  101. if(Find_Trie(str)) puts("Yes");
  102. else puts("No");
  103. }
  104. }DelTrie(Root);
  105. return ;
  106. }

HDU 5687 Problem C 【字典树删除】的更多相关文章

  1. HDU 5687 Problem C ( 字典树前缀增删查 )

    题意 : 度熊手上有一本神奇的字典,你可以在它里面做如下三个操作: 1.insert : 往神奇字典中插入一个单词 2.delete: 在神奇字典中删除所有前缀等于给定字符串的单词 3.search: ...

  2. hdu 5687 Problem C trie树

    Problem C Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Prob ...

  3. hdu 1671 Phone List 字典树

    // hdu 1671 Phone List 字典树 // // 题目大意: // // 有一些电话号码的字符串长度最多是10,问是否存在字符串是其它字符串的前缀 // // // 解题思路: // ...

  4. HDU 5536 Chip Factory 【01字典树删除】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5536 Chip Factory Time Limit: 18000/9000 MS (Java/Ot ...

  5. Chip Factory HDU - 5536 字典树(删除节点|增加节点)

    题意: t组样例,对于每一组样例第一行输入一个n,下面在输入n个数 你需要从这n个数里面找出来三个数(设为x,y,z),找出来(x+y)^z(同样也可以(y+z)^1)的最大值 ("^&qu ...

  6. HDU 5687 Problem C(Trie+坑)

    Problem C Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Tota ...

  7. HDU 5536 Chip Factory 字典树

    Chip Factory Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  8. HDU 5536 Chip Factory 字典树+贪心

    给你n个数,a1....an,求(ai+aj)^ak最大的值,i不等于j不等于k 思路:先建字典树,暴力i,j每次删除他们,然后贪心找k,再恢复i,j,每次和答案取较大的,就是答案,有关异或的貌似很多 ...

  9. hdu 6059---Kanade's trio(字典树)

    题目链接 Problem Description Give you an array A[1..n],you need to calculate how many tuples (i,j,k) sat ...

随机推荐

  1. PIXI 精灵及文本加载(4)

    预习下官网的知识. 及字母消除接上文 Pixi 精灵 Pixi拥有一个精灵类来创建游戏精灵.有三种主要的方法来创建它: 用一个单图像文件创建. 用一个 雪碧图 来创建.雪碧图是一个放入了你游戏所需的所 ...

  2. webstorm 搜索vue文件

    1. Show IDE settings 状态修改为 ON

  3. vue生命周期及使用 && 单文件组件下的生命周期

    生命周期钩子 这篇文章主要记录与生命周期相关的问题. 之前,我们讲到过生命周期,如下所示: 根据图示我们很容易理解vue的生命周期: js执行到new Vue() 后,即进入vue的beforeCre ...

  4. [转]一种可以避免数据迁移的分库分表scale-out扩容方式

    原文地址:http://jm-blog.aliapp.com/?p=590 目前绝大多数应用采取的两种分库分表规则 mod方式 dayofweek系列日期方式(所有星期1的数据在一个库/表,或所有?月 ...

  5. git命令(转载学习)

    Git使用教程 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是 ...

  6. 【LDAP】ldap目录服务的命名模型

    ldap的命名模型 命名模型规定了在目录中如何组织和表示条目 1.   目录信息树(DIT) 目录信息树有点类似于DNS的结构.每一个条目都有自己的父条目(因为主条目的父条目是top,所以这句话是成立 ...

  7. java 中String编码和byte 解码总结——字节流和字符流

    1.InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符 InputStreamReader(InputStream in, Strin ...

  8. http反向代理之haproxy详解

    1.反向代理定义 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求 ...

  9. Enjoy coding

    Enjoy coding iTerm配置 主题选择 Solarized Dark LiquidCarbon 字体选择 Cousine for Powerline(需要安装Powerline字体库), ...

  10. jquery中Ajax提交配合PHP使用的注意事项-编码

    问题:Ajax提交的数据的编码为utf-8,并且返回的数据也要求是utf-8的,如果说你的系统不是utf-8编码的话,那会让你痛不欲生! 解决方法:(比较笨拙的方法,但是很好用) 对于接收的数据,使用 ...