字典树

01 字典树的认识与基本模型

主宰稳场 提交于 2019-11-30 07:14:36
01字典树是字典树的一个分支 :推荐博客(字典树) https://blog.csdn.net/weixin_39778570/article/details/81990417 里面有原理图 , 01字典树就是插入01串; 01字典树是解决异或最值问题的一大煞气,实现简单,但结合应用较为困难 const int maxn = 100000 + 5; //集合中的数字个数 typedef long long LL; int ch[32 * maxn][2]; //节点的边信息 LL value[32 * maxn]; //节点存储的值 int node_cnt; //树中当前节点个数 inline void init(){ //树清空 node_cnt = 1; memset(ch[0],0,sizeof(ch[0])); } inline void Insert(LL x){ //在字典树中插入 X //和一般字典树的操作相同 将X的二进制插入到字典树中 int cur = 0; for(int i = 32;i >= 0;--i){ int idx = (x >> i) & 1; if(!ch[cur][idx]){ memset(ch[node_cnt],0,sizeof(ch[node_cnt])); ch[cur][idx] = node_cnt; value[node

「字典树」最大异或对

人走茶凉 提交于 2019-11-29 18:29:06
最大异或对 原题链接: 最大异或对 题目大意 给你 \(n\) 个数,从中选两个数进行异或运算,得到结果最大是多少 题目题解 一道没写过就不知道怎么写的套路题 刚开始可以用贪心分析,也就是说如果两个数的高位能够尽可能的大那么我们就尽可能的大就好了,也就是说两个数的二进制数在同一位不同,此时最大,那么怎样很快的满足呢?我们发现可以将二进制数转化到Trie上面解决,当前是1就尽可能走0,当前是0就尽可能走1,那这个问题就很简单了,建个Trie数直接跑就好了 //#define fre yes #include <cstdio> #include <iostream> const int N = 100005; struct Node { int son[2]; } trie[N * 30]; int a[N], idx; void Insert(int x) { int rt = 0; for (int i = 30; i >= 0; i--) { int id = x >> i & 1; if(!trie[rt].son[id]) trie[rt].son[id] = ++idx; rt = trie[rt].son[id]; } } int Search(int x) { int rt = 0, ans = 0; for (int i = 30; i >= 0; i--) {

hdu6625 three arrays (01字典树)

丶灬走出姿态 提交于 2019-11-29 08:20:17
Problem Description There are three integer arrays a,b,c. The lengths of them are all N. You are given the full contents of a and b. And the elements in c is produced by following equation: c[i]=a[i] XOR b[i] where XOR is the bitwise exclusive or operation. Now you can rearrange the order of elements in arrays a and b independently before generating the array c. We ask you to produce the lexicographically smallest possible array c after reordering a and b. Please output the resulting array c. Input The first line contains an integer T indicating there are T tests. Each test consists of three

字典树(模板

╄→гoц情女王★ 提交于 2019-11-28 09:42:49
学完字典树后    还是背不住模板…………介绍写在代码里———— struct Trie{ ll ch[N][26],sz,val[N]; //val为附加信息 //这里的ch数组,第二维的大小为26是因为字符串只由小写字母构成,第二维的大小一般是由字符串的组成决定 //sz即为节点编号 Trie(){ sz=1;//一开始的时候只有根节点这一个节点 memset(ch[0],0,sizeof(ch[0])); memset(val,0,sizeof(val)); }//这里是初始化 ll idx(char c){return c-'a';}//返回字符c的编号 void insert(char *s,ll v){ //插入操作 ,这里是整份代码中唯一用到指针的地方,因为函数是放在结构体里面 ,所以最好用个指针,其实等价于char s[] //s代表要插入的字符串,v为附加信息 ll u=0,len=strlen(s+1); for(ll i=1;i<=len;i++){ ll c=idx(s[i]); if(!ch[u][c]){//如果节点不存在就插入,不然就继续往下遍历 memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0;//中间的节点是没有附加信息的 ch[u][c]=sz++;//新建节点 } u=ch[u][c];//往下遍历 }

cogs 173. 词链 字典树模板

与世无争的帅哥 提交于 2019-11-28 06:20:25
173. 词链 ★★☆ 输入文件: link.in 输出文件: link.out 简单对比 时间限制:1 s 内存限制:128 MB 【问题描述】 给定一个仅包含小写字母的英文单词表,其中每个单词最多包含 50 个字母。 如果一张由一个词或多个词组成的表中,每个单词(除了最后一个)都是排在它后面的单词的前缀,则称此表为一个词链。例如下面的单词组成了一个词链: i int integer 而下面的单词不组成词链: integer intern 请在给定的单词表中取出一些词,组成最长的词链。最长的词链就是包含单词数最多的词链。 数据保证给定的单词表中,单词互不相同,并且单词按字典顺序排列。 【输入格式】 第一行一个整数 n ,表示单词表中单词数。 下接 n 行每行一个单词。 【输出格式】 一个整数,表示最长词链长度。 【输入输出样例】 输入: link.in 5 i int integer intern internet 输出: link.out 4 【数据范围】 50% 的数据, n<=1000 100% 的数据, n<=10000 这一道题的标签看起来好吓人:动态规划 本人准备打破常规 来用字典树做一下(很明显能够看出来 我不会用dp做) 也就是说在字典树上找出 字符串结尾的数量最多的一条链 保存最大值即可 在这一条链上字符串都是后面的前缀(仔细想想就发现这是很显然的)

【模板】 字典树

眉间皱痕 提交于 2019-11-28 04:15:23
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 struct node{ 6 int cnt; //记录出现次数 7 int nex[30];//该节点下一个儿子的节点 8 }trie[400500]; 9 char s1[105],s2[105]; 10 int tot=1;//也可以0 11 void build(char* s){ 12 int len=strlen(s); 13 int root=0; 14 for(int i=0;i<len;++i){ 15 int id=s[i]-'a'; 16 if(trie[root].nex[id]==0) trie[root].nex[id]=++tot; 17 root=trie[root].nex[id]; 18 ++trie[root].cnt; 19 } 20 } 21 int query(char* s){ 22 int len=strlen(s); 23 int root=0; 24 for(int i=0;i<len;++i){ 25 int id=s[i]-'a'; 26 if(!trie[root].nex[id]) return 0; 27 root=trie[root].nex[id];

Hat’s Words HDU - 1247 (字典树)

北城以北 提交于 2019-11-28 02:02:04
Hat’s Words HDU - 1247 题目链接: https://vjudge.net/problem/HDU-1247 题目: A hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary. You are to find all the hat’s words in a dictionary. InputStandard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 50,000 words. Only one case. OutputYour output should contain all the hat’s words, one per line, in alphabetical order.Sample Input a ahat hat hatword hziee word Sample Output ahat hatword题意:就是给你一个单词列表,然后单词可以从中间拆成任意两部分

Phone List HDU - 1671(字典树)

£可爱£侵袭症+ 提交于 2019-11-28 01:42:57
Phone List HDU - 1671 题目链接: https://vjudge.net/problem/HDU-1671 题目: 给出一个电话号码列表,确定它是否一致,因为没有数字是另一个号码的前缀。 假设电话目录列出了这些数字: 1. Emergency 911 2. Alice 97 625 999 3. Bob 91 12 54 26 在这种情况下,无法呼叫Bob,因为只要您拨打了Bob的电话号码的前三位数字,中心就会将您的呼叫转接到紧急线路。 所以这个列表不一致。 输入 第一行输入给出一个整数,1 <= t <= 40,即测试用例的数量。 每个测试用例以n(电话号码的数量)在单独的行上开始,1 <= n <= 10000.然后是n行,每行有一个唯一的电话号码。 电话号码是最多十位数的序列。 产量 对于每个测试用例,如果列表一致则输出“YES”,否则输出“NO”。 思路:将这些电话号码插入字典树中,只要出现一个电话号码是另一个电话号码的前缀,那么就输出“NO”否则输出“YES”, 这题要注意内存的控制,否则会MLE,还有不能n方来利用find前缀函数判断每一个字符串在其他字符串是否是前缀,否则会TLE, 只要在将电话号码插入字典树的时候判断p->num是否不为0即可,如果不为0就break,很好的避免了n方判断、 // // Created by HJYL on

Flying to the Mars HDU - 1800(字典树)

元气小坏坏 提交于 2019-11-28 01:24:49
Flying to the Mars HDU - 1800 题目链接: https://vjudge.net/problem/HDU-1800 题目: 在8888年,地球由PPF帝国统治。随着人口的增长,PPF需要为新生儿寻找更多的土地。最后,PPF决定攻击统治火星的Kscinow。问题来了!士兵怎么能到达火星? PPF召集他的士兵并询问他们的建议。 “匆匆......”一名士兵回答。 “闭嘴 !我是否必须提醒你,从这里到火星没有任何道路!“PPF回复道。 “飞!”另一个答案。 PPF笑道:“聪明的家伙!虽然我们没有翅膀,但我可以从HARRY POTTER购买一些魔法扫帚来帮助你。“现在,是时候学会用扫帚飞行了!我们假设一名士兵有一个级别数字表示他的学位。具有较高等级的士兵可以教低级,也就是说前者的等级>后者。但是较低的不能教更高。一名士兵最多只能有一名教师,当然,没有老师也是合法的。同样,一名士兵最多只能有一名学生,而没有学生也是可能的。老师可以用同样的扫帚教他的学生。当然,所有的士兵都必须在扫帚上练习才能飞到火星上!魔法扫帚是昂贵的!所以,你能帮助PPF计算所需的最小扫帚数量。 例如 : 有5名士兵(A B C D E),等级编号:2 4 5 6 4; 一种方法: C可以教B; B可以教A;因此,A B C有资格在同一个扫帚上学习。 D可以教E;所以D

统计难题 HDU - 1251(字典树)

邮差的信 提交于 2019-11-27 16:53:39
统计难题 HDU - 1251 题目链接: https://vjudge.net/problem/HDU-1251 Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output对于每个提问,给出以该字符串为前缀的单词的数量. Sample Input banana band bee absolute acm ba b band abc Sample Output 2 3 1 0思路:字典树模板 // // Created by HJYL on 2019/8/17. // #include <iostream> #include <vector> #include <map> #include <string> #include <queue> #include <stack> #include <set> #include <algorithm> #include <cstdio> #include