传..传送: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:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define INF 0x3f3f3f3f
#define LL long long int
#define Bits 26
using namespace std;
const int MAXN = ;
int N;
struct Trie
{
Trie *next[Bits];
int flag;
inline void init(){
this->flag = ;
for(int i = ; i < Bits; i++)
this->next[i] = NULL;
}
};
Trie *Root = (Trie *)malloc(sizeof(Trie));
inline void DelTrie(Trie *t)
{
if(t == NULL) return;
for(int i = ; i < Bits; i++){
if(t->next[i]!=NULL) DelTrie(t->next[i]);
}free(t);
return;
} void Create_Trie(char *str, bool isDel)
{
int len = strlen(str);
Trie *p = Root, *temp;
int Delnum = ;
for(int i = ; i < len; i++){
int index = str[i]-'a';
if(!isDel){
if(p->next[index] == NULL){
temp = (Trie *)malloc(sizeof(Trie));
temp->init();
p->next[index] = temp;
p = p->next[index];
}
else{p->next[index]->flag+=; p=p->next[index];}
}
else{
if(p->next[index] != NULL){
Delnum = p->next[index]->flag;
p = p->next[index];
}else return;
}
}
if(isDel){
p = Root;
for(int i = ; i < len; i++){
int index = str[i]-'a';
if(p->next[index] == NULL) return;
if(i==len-){
DelTrie(p->next[index]);
p->next[index] = NULL;
return;
}
p->next[index]->flag-=Delnum;
p = p->next[index];
}
}
} bool Find_Trie(char *str)
{
int len = strlen(str);
Trie *p = Root;
for(int i = ; i < len; i++){
int index = str[i]-'a';
if(p->next[index] != NULL && p->next[index]->flag > )
p=p->next[index];
else return false;
}return true;
} int main()
{
Root->init();
scanf("%d", &N);
char str[MAXN], command[];
while(N--){
scanf("%s", command);
if(strcmp(command, "insert")==){
scanf("%s", str);
Create_Trie(str, false);
}
else if(strcmp(command, "delete")==){
//puts("zjj");
scanf("%s", str);
Create_Trie(str, true);
}
else{
scanf("%s", str);
if(Find_Trie(str)) puts("Yes");
else puts("No");
}
}DelTrie(Root);
return ;
}

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. mongodb insert()、save()的区别

    mongodb 的 insert().save()  ,区别主要是:若存在主键,insert()  不做操作,而save() 则更改原来的内容为新内容. 存在数据:  { _id : 1, " ...

  2. HDU 1069—— Monkey and Banana——————【dp】

    Monkey and Banana Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  3. java 读写操作大文件 BufferedReader和RandomAccessFile

    一 老问这问题,两个都答出来算加分项? 二 具体代码如下,没什么好说的直接说对比. BufferedReader和RandomAccessFile的区别RandomAccessFile 在数据越大,性 ...

  4. Java原生隐藏字符-工具类

    package com.seesun2012.common.util; /** 隐藏字符-工具类 @author seesun2012@163.com */ public class HiddenCh ...

  5. Node.js之Buffer

    JavaScript 语言自身只有字符串数据类型,没有二进制数据类型.但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存 ...

  6. Spring Chapter4 WebSocket 胡乱翻译 (一) 一个例子

    因为没有基础,不知道从哪里入手. 文档里的例子,https://github.com/rstoyanchev/spring-websocket-portfolio,这个除了WebSocket,还整了S ...

  7. NIOSocket Server Client

    最近在看Netty框架,顺便写了一下NIO SocketChannel服务端和客户端 Server.java import java.io.IOException; import java.net.I ...

  8. js正则验证表达式

    //上传文件大小验证 $.fn.checkFileTypeAndSize = function (options) { //默认设置 var defaults = { allowedExtension ...

  9. SQLAlchemy的使用---外键ForeignKey数据增删改查

    # 添加数据 from sqlalchemy.orm import sessionmaker from create_table_ForeignKey import engine, Student, ...

  10. HTML字符实体名称/实体编号

    字符实体对英文的大小写敏感! 字符实体一: 显示结果 描述 实体名称 实体编号   空格     < 小于号 < < > 大于号 > > & 和号 & ...