[您有新的未分配科技点]可,可,可持久化!?------0-1Trie和可持久化Trie普及版讲解
2017-08-03 20:42
281 查看
这一次,我们来了解普通Trie树的变种:0-1Trie以及在其基础上产生的可持久化Trie(其实,普通的Trie也可以可持久化,只是不太常见)
先简单介绍一下0-1Trie:一个0-1Trie节点只有两个子节点,分别代表0和1;从根节点开始,第一层代表限制的最高位,依次往下直到最底层,代表二进制第0位。
0-1Trie上的一条链所表示的数字,就是Trie树中的一个数字。0-1Trie除了节点和插入方式与普通的Trie树略有不同之外,其他操作都是和Trie树完全一样的。在维护这个节点插入过的数的个数size之后,0-1Trie甚至可以做一些平衡树的题……
下面给2道比较简单的例题:
bzoj3689 异或之 http://www.lydsy.com/JudgeOnline/problem.php?id=3689
bzoj3224 普通平衡树 http://www.lydsy.com/JudgeOnline/problem.php?id=3224
值得注意的是,0-1Trie无法处理负权值,因此,我们可以给每个数加上一个大的修正值delta,使得所有值都成为非负的。最后我们在减去delta即可。
下面给出0-1Trie版的普通平衡树代码,很短,但是的确可以AC:
接下来,我们在0-1Trie的基础上,介绍可持久化Trie。
可持久化Trie树和前面两种可持久化数据结构一样,也是通过复制节点来实现可持久化操作。
在插入的时候,我们也是复制路径上的节点,由于可持久化Trie和主席树一样具有区间可减性,所以我们直接像主席树那样区间相减即可。
具体代码,长得和之前的可持久化Treap差不多……下面给出插入的代码(可能比较丑……)
可持久化Trie树经常用来处理与异或有关的k小问题。一般来说,我们都是把0-1Trie可持久化来维护数字运算,很少有把字符串的Trie可持久化的题目。
这里再给出两道可持久化Trie的基础题:
bzoj4103[Thu Summer Camp 2015]异或运算 http://www.lydsy.com/JudgeOnline/problem.php?id=4103
我的题解:http://www.cnblogs.com/LadyLex/p/7281945.html
bzoj3166[Heoi2013]Alo http://www.lydsy.com/JudgeOnline/problem.php?id=3166
我的题解:http://www.cnblogs.com/LadyLex/p/7281860.html
可持久化Trie是一种和主席树同样优秀的数据结构,无疑是一种新的解题思路。希望大家能从我的博客中有所收获:)
先简单介绍一下0-1Trie:一个0-1Trie节点只有两个子节点,分别代表0和1;从根节点开始,第一层代表限制的最高位,依次往下直到最底层,代表二进制第0位。
0-1Trie上的一条链所表示的数字,就是Trie树中的一个数字。0-1Trie除了节点和插入方式与普通的Trie树略有不同之外,其他操作都是和Trie树完全一样的。在维护这个节点插入过的数的个数size之后,0-1Trie甚至可以做一些平衡树的题……
下面给2道比较简单的例题:
bzoj3689 异或之 http://www.lydsy.com/JudgeOnline/problem.php?id=3689
bzoj3224 普通平衡树 http://www.lydsy.com/JudgeOnline/problem.php?id=3224
值得注意的是,0-1Trie无法处理负权值,因此,我们可以给每个数加上一个大的修正值delta,使得所有值都成为非负的。最后我们在减去delta即可。
下面给出0-1Trie版的普通平衡树代码,很短,但是的确可以AC:
#include <cstdio> #include <cstring> using namespace std; typedef long long LL; const int inf=0x7fffffff,delta=10000100; LL bin[50]; struct Trie { Trie *ch[2];int size; Trie(){size=0;ch[1]=ch[0]=NULL;} }*null=new Trie(),*root; inline Trie* newTrie(){Trie *o=new Trie();o->ch[0]=o->ch[1]=null;return o;} inline void insert(int x) { Trie *rt=root; for(int i=30;~i;i--) { int d=(x&bin[i])>>i; if(rt->ch[d]==null)rt->ch[d]=newTrie(); rt=rt->ch[d],rt->size++; } } inline void del(int x) { Trie *rt=root; for(int i=30;~i;i--) rt=rt->ch[(x&bin[i])>>i],rt->size--; } inline int getrank(int x) { Trie *rt=root;int ret=0; for(int i=30;~i;i--) { if((x&bin[i])>>i)ret+=rt->ch[0]->size; rt=rt->ch[(x&bin[i])>>i]; } return ret; } inline int getval(int rank) { Trie *rt=root;int ret=0; for(int i=30;~i;i--) { if(rt->ch[0]->size>=rank)rt=rt->ch[0]; else rank-=rt->ch[0]->size,ret|=bin[i],rt=rt->ch[1]; } return ret; } int main() { bin[0]=1;for(int i=1;i<=40;i++)bin[i]=bin[i-1]<<1; root=newTrie();null->ch[0]=null->ch[1]=null; int m,opt,x;scanf("%d",&m); while(m--) { scanf("%d%d",&opt,&x); switch(opt) { case 1:insert(x+delta);break; case 2:del(x+delta);break; case 3:printf("%d\n",getrank(x+delta)+1);break; case 4:printf("%d\n",getval(x)-delta);break; case 5:printf("%d\n",getval(getrank(x+delta))-delta);break; case 6:printf("%d\n",getval(getrank(x+delta+1)+1)-delta);break; } } }
接下来,我们在0-1Trie的基础上,介绍可持久化Trie。
可持久化Trie树和前面两种可持久化数据结构一样,也是通过复制节点来实现可持久化操作。
在插入的时候,我们也是复制路径上的节点,由于可持久化Trie和主席树一样具有区间可减性,所以我们直接像主席树那样区间相减即可。
具体代码,长得和之前的可持久化Treap差不多……下面给出插入的代码(可能比较丑……)
//bin[i]数组为预处理的2的i次方 void insert(Trie *&o,Trie *old,int val,int i) { if(i<0)return; int d=((val&bin[i])==bin[i]);//判断当前为是0还是1 o->ch[d]=newTrie();o->ch[d^1]=old->ch[d^1]; o->ch[d]->size=old->ch[d]->size+1; insert(o->ch[d],old->ch[d],val,i-1); }
可持久化Trie树经常用来处理与异或有关的k小问题。一般来说,我们都是把0-1Trie可持久化来维护数字运算,很少有把字符串的Trie可持久化的题目。
这里再给出两道可持久化Trie的基础题:
bzoj4103[Thu Summer Camp 2015]异或运算 http://www.lydsy.com/JudgeOnline/problem.php?id=4103
我的题解:http://www.cnblogs.com/LadyLex/p/7281945.html
bzoj3166[Heoi2013]Alo http://www.lydsy.com/JudgeOnline/problem.php?id=3166
我的题解:http://www.cnblogs.com/LadyLex/p/7281860.html
可持久化Trie是一种和主席树同样优秀的数据结构,无疑是一种新的解题思路。希望大家能从我的博客中有所收获:)
相关文章推荐
- [您有新的未分配科技点]可,可,可持久化!?------可持久化线段树普及版讲解
- [您有新的未分配科技点]可,可,可持久化!?------可持久化平衡树普及版讲解
- 动态内存分配讲解
- [BZOJ 3674]可持久化并查集加强版:可持久化并查集
- BZOJ 2741【FOTILE模拟赛】L 分块+可持久化trie
- 【CodeChef-XRQRS】Xor Queries【可持久化Trie / +主席树】
- BZOJ 3674: 可持久化并查集加强版 可持久化并查集
- 【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L
- [POJ2104]K-th Number(主席树+讲解+可持久化基础)
- JAVA内存存储分配粗略讲解
- 【bzoj3166】【HEOI2013】【Alo】【set+可持久化trie】
- 【BZOJ4260】 Codechef REBXOR 可持久化Trie
- 尚学堂科技_马士兵_JAVA_网上商城项目视频讲解
- BZOJ 4103 [Thu Summer Camp 2015]异或运算 可持久化Trie
- BZOJ2741 FOTILE模拟赛L(分块+可持久化trie)
- bzoj 2741: 【FOTILE模拟赛】L 分塊+可持久化trie
- Lync 项目经验-37-分配公网证书 For SFB 2015-持久聊天服务器(图解)
- [BZOJ 4103] [Thu Summer Camp 2015] 异或运算 【可持久化Trie】
- task活动讲解之任务分配,候选,自定义任务分配处理器
- hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)