[HDU5687]2016"百度之星" - 资格赛 Problem C

题目大意:有n个操作,每个操作是以下三个之一,要你实现这些操作。

1、insert : 往字典中插入一个单词
2、delete: 在字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在字典中有一个字符串的前缀等于给定的字符串

解题思路:Trie树即可。

注意代码第49行的判断,我当时以为只要成功搜到这个前缀就一定有答案,忽略了删除操作使某些前缀的单词数为0的情况。

C++ Code:

#include<cstdio>
struct node{
	int cnt;
	node* nxt[27];
	node():cnt(0){for(int i=0;i<26;++i)nxt[i]=NULL;}
}*d;
char s[40];
void ins(char* s){
	++d->cnt;
	node *now=d;
	for(int i=0;s[i];++i){
		int v=s[i]-‘a‘;
		if(now->nxt[v]==NULL)now->nxt[v]=new node;
		now=now->nxt[v];
		++now->cnt;
	}
}
void clear(node* p){
	for(int i=0;i<26;++i)
	if(p->nxt[i]!=NULL)clear(p->nxt[i]);
	delete p;
}
void del(char* s){
	node* p=d,*pre=p;
	int v;
	for(int i=0;s[i];++i){
		v=s[i]-‘a‘;
		if(p->nxt[v]==NULL)return;
		pre=p;
		p=p->nxt[v];
	}
	int num=p->cnt;
	clear(p);
	pre->nxt[v]=NULL;
	p=d;
	for(int i=0;;++i){
		p=p->nxt[s[i]-‘a‘];
		if(p==NULL)break;
		p->cnt-=num;
	}
}
bool ask(char* s){
	node* p=d;
	for(int i=0;s[i];++i){
		int v=s[i]-‘a‘;
		p=p->nxt[v];
		if(p==NULL)return false;
	}
	if(p->cnt<1)return false;
	return true;
}
int main(){
	d=new node;
	int n;
	scanf("%d",&n);
	while(n--){
		scanf("%s",s);
		if(s[0]==‘i‘){
			scanf("%s",s);
			ins(s);
		}else
		if(s[0]==‘d‘){
			scanf("%s",s);
			del(s);
		}else{
			scanf("%s",s);
			if(ask(s))puts("Yes");else
			puts("No");
		}
	}
	return 0;
}
时间: 2024-11-05 13:40:50

[HDU5687]2016"百度之星" - 资格赛 Problem C的相关文章

[HDU5685]2016&quot;百度之星&quot; - 资格赛 Problem A

题目大意:给你一个字符串,和一些问题,每个问题问你[l,r]子串的哈希值是多少. 哈希值计算方法为:$H(s)=\prod _{i=1} ^{i\leq len(s)}(s_i-28)(mod\ 9973)$. 其中$s_i$代表 S[i] 字符的 ASCII 码. 解题思路:我们知道,要算区间[l,r]所有的和,就可以用$O(n)$的时间预处理出数组t,令$t[i]$表示前i个数的和,那么$t[r]-t[l-1]$即为区间[l,r]所有之和,询问时间复杂度$O(1)$,这就是维护前缀和的做法.

[HDU5686]2016&quot;百度之星&quot; - 资格赛 Problem B

题目大意:给你n,规定一个串中相邻的两个1可以合并为一个2(别的不行),让你求长度为n的全1串最多能变成多少种不同的串. 解题思路:我们先来找一波规律,发现n=1,2,3,4,5时答案分别为1,2,3,5,8. 嗯?斐波那契数列?没错就是这样.不过斐波那契数列的第200项好像有四五十位,long long也存不下? Java大法好,不用打烦人的高精度!当然时间就比较慢了. Java Code: import java.io.*; import java.math.*; import java.u

2016百度之星资格赛 Problem A(前缀积与求逆元)

题意:给出一个字符串,每次询问给出x和y要求算出从x到y的每个字符的(ASCII 码值-28)的值的积(mod9973). 分析:首先的想法肯定是算出每个位置的前缀积,然后只要F[y]/F[x-1]即可.但是每个前缀积都已经mod9973了,就不能直接这样得出结果了,所以利用求逆元.因为a/b(mod p)p是奇数的话,相当于a*inv(b) (mod p),所以只要保存每个位置的前缀积和前缀积的逆元就可以了. 但是题目有个坑点,如果x和y超出了这次字符串的位置,可以使用上一次数据储存的值而不是

[HDU5688]2016&quot;百度之星&quot; - 资格赛 Problem D

题目大意:给你n个字符串,如果一个字符串可以通过重新排列变成另一个字符串,则认为这两个字符串相等.每输入一个字符串,输出这个字符串和与它相等的之前出现了几次. 解题思路:我们可以用map保存一个字符串出现的次数,对于每个读进来的串,先把它排序一遍即可.由于字符串长度最大只有40,排序时间几乎可以忽略. 于是时间复杂度就只有map的$O(n\log n)$了. C++ Code: #include<iostream> #include<map> #include<algorit

2016&quot;百度之星&quot; - 资格赛(Astar Round1) Problem D 简单题

Problem D Accepts: 1527 Submissions: 4307 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊所居住的 D 国,是一个完全尊重人权的国度.以至于这个国家的所有人命名自己的名字都非常奇怪.一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字.例如,如果一个人名字

hdu 5685 Problem A(2016&quot;百度之星&quot; - 资格赛(Astar Round1)——线段树)

题目链接:acm.hdu.edu.cn/showproblem.php?pid=5685 Problem A Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 564    Accepted Submission(s): 236 Problem Description 度熊手上有一本字典存储了大量的单词,有一次,他把所有单词组成了一个很长

2016&quot;百度之星&quot; - 资格赛 解题报告

这次的百度之星,不得不吐槽下系统的判题数据,被坑了不知多少次. 第一题:大意:求一段区间的累乘.用线段树即可.坑点:如果询问范围超出边界,输出上一次的结果. /* Problem : Status : By wf, */ #include "algorithm" #include "iostream" #include "cstring" #include "cstdio" #include "string"

Problem A(逆元) 2016&quot;百度之星&quot; - 资格赛(Astar Round1)

Problem A Accepts: 1515 Submissions: 10832 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊手上有一本字典存储了大量的单词,有一次,他把所有单词组成了一个很长很长的字符串.现在麻烦来了,他忘记了原来的字符串都是什么,神奇的是他竟然记得原来那些字符串的哈希值.一个字符串的哈希值,由以下公式计算得到:

Problem C (字典树的查找删除和插入)2016&quot;百度之星&quot; - 资格赛(Astar Round1)

Problem C Accepts: 630 Submissions: 5255 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Description 度熊手上有一本神奇的字典,你可以在它里面做如下三个操作: 1.insert : 往神奇字典中插入一个单词 2.delete: 在神奇字典中删除所有前缀等于给定字符串的单词 3.search: 查询是否在神奇字典中