01字典树及其模板
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了01字典树及其模板相关的知识,希望对你有一定的参考价值。
模板 :
const int Bit = 32; struct Trie { Trie *ch[2]; LL v; inline void init(){ for(int i=0; i<2; i++) this->ch[i] = NULL; this->v = -1; } }; Trie *root;///记得在 main 函数的时候分配空间给 root 并初始化 inline void CreateTrie(LL x) { Trie * p = root, *tmp; for(int i=Bit; i>=0; i--){ int idx = (x>>i)&1; if(p->ch[idx] == NULL){ tmp = (Trie *)malloc(sizeof(Trie)); tmp->init(); p->ch[idx] = tmp; }//else //加个权值啥的 p = p->ch[idx]; } p->v = x;///在结尾打上标记,表示这串二进制的十进制表示是多少 } LL Query(LL x) { Trie *p = root; for(int i=Bit; i>=0; i--){ int idx = (x>>i)&1; if(p->ch[idx^1]){ p = p->ch[idx^1]; }else p = p->ch[idx]; } return p->v; } inline void DelTrie(Trie *T) { if(T == NULL) return ; for(int i=0; i<2; i++){ if(T->ch[i]){ DelTrie(T->ch[i]); } }free(T); }
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)); } 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_cnt++] = 0; } cur = ch[cur][idx]; } value[cur] = x; //最后的节点插入value } LL Query(LL x){ //在字典树中查找和X异或的最大值的元素Y 返回Y的值 int cur = 0; for(int i = 32;i >= 0;--i){ int idx = (x >> i) & 1; if(ch[cur][idx ^ 1]) cur = ch[cur][idx ^ 1]; else cur = ch[cur][idx]; } return value[cur]; }
01字典树是求区间连续的异或和以及异或最大值的有利工具
参考博客 ==>
http://blog.csdn.net/guhaiteng/article/details/52191831
http://blog.csdn.net/solardomo/article/details/52168853
http://blog.csdn.net/miracle_ma/article/details/51484054
相关题目 :
以上是关于01字典树及其模板的主要内容,如果未能解决你的问题,请参考以下文章