[您有新的未分配科技点]可,可,可持久化!?------0-1Trie和可持久化Trie普及版讲解
这一次,我们来了解普通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:
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int inf=0x7fffffff,delta=;
LL bin[];
struct Trie
{
Trie *ch[];int size;
Trie(){size=;ch[]=ch[]=NULL;}
}*null=new Trie(),*root;
inline Trie* newTrie(){Trie *o=new Trie();o->ch[]=o->ch[]=null;return o;}
inline void insert(int x)
{
Trie *rt=root;
for(int i=;~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=;~i;i--)
rt=rt->ch[(x&bin[i])>>i],rt->size--;
}
inline int getrank(int x)
{
Trie *rt=root;int ret=;
for(int i=;~i;i--)
{
if((x&bin[i])>>i)ret+=rt->ch[]->size;
rt=rt->ch[(x&bin[i])>>i];
}
return ret;
}
inline int getval(int rank)
{
Trie *rt=root;int ret=;
for(int i=;~i;i--)
{
if(rt->ch[]->size>=rank)rt=rt->ch[];
else rank-=rt->ch[]->size,ret|=bin[i],rt=rt->ch[];
}
return ret;
}
int main()
{
bin[]=;for(int i=;i<=;i++)bin[i]=bin[i-]<<;
root=newTrie();null->ch[]=null->ch[]=null;
int m,opt,x;scanf("%d",&m);
while(m--)
{
scanf("%d%d",&opt,&x);
switch(opt)
{
case :insert(x+delta);break;
case :del(x+delta);break;
case :printf("%d\n",getrank(x+delta)+);break;
case :printf("%d\n",getval(x)-delta);break;
case :printf("%d\n",getval(getrank(x+delta))-delta);break;
case :printf("%d\n",getval(getrank(x+delta+)+)-delta);break;
}
}
}
接下来,我们在0-1Trie的基础上,介绍可持久化Trie。
可持久化Trie树和前面两种可持久化数据结构一样,也是通过复制节点来实现可持久化操作。
在插入的时候,我们也是复制路径上的节点,由于可持久化Trie和主席树一样具有区间可减性,所以我们直接像主席树那样区间相减即可。
具体代码,长得和之前的可持久化Treap差不多……下面给出插入的代码(可能比较丑……)
//bin[i]数组为预处理的2的i次方
void insert(Trie *&o,Trie *old,int val,int i)
{
if(i<)return;
int d=((val&bin[i])==bin[i]);//判断当前为是0还是1
o->ch[d]=newTrie();o->ch[d^]=old->ch[d^];
o->ch[d]->size=old->ch[d]->size+;
insert(o->ch[d],old->ch[d],val,i-);
}
可持久化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和可持久化Trie普及版讲解的更多相关文章
- [您有新的未分配科技点] 无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MB Description Input 输入的第1 行包含两个数N 和M(M ≤20 ...
- [您有新的未分配科技点]博弈论进阶:似乎不那么恐惧了…… (SJ定理,简单的基础模型)
这次,我们来继续学习博弈论的知识.今天我们会学习更多的基础模型,以及SJ定理的应用. 首先,我们来看博弈论在DAG上的应用.首先来看一个小例子:在一个有向无环图中,有一个棋子从某一个点开始一直向它的出 ...
- [您有新的未分配科技点]博弈论入门:被博弈论支配的恐惧(Nim游戏,SG函数)
今天初步学习了一下博弈论……感觉真的是好精妙啊……希望这篇博客可以帮助到和我一样刚学习博弈论的同学们. 博弈论,又被称为对策论,被用于考虑游戏中个体的预测行为和实际行为,并研究他们的应用策略.(其实这 ...
- [您有新的未分配科技点]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)
今天我们来学习一种新的数据结构:无旋treap.它和splay一样支持区间操作,和treap一样简单易懂,同时还支持可持久化. 无旋treap的节点定义和treap一样,都要同时满足树性质和堆性质,我 ...
- [您有新的未分配科技点]数位DP:从板子到基础(例题 bzoj1026 windy数 bzoj3131 淘金)
只会统计数位个数或者某种”符合简单规律”的数并不够……我们需要更多的套路和应用 数位dp中常用的思想是“分类讨论”思想.下面我们就看一道典型的分类讨论例题 1026: [SCOI2009]windy数 ...
- [您有新的未分配科技点]数位dp:从懵X到板子(例题:HDU2089 不要62)
数位dp主要用来处理一系列需要数数的问题,一般套路为“求[l,r]区间内满足要求的数/数位的个数” 要求五花八门……比如“不出现某个数字序列”,“某种数的出现次数”等等…… 面对这种数数题,暴力的想法 ...
- [您有新的未分配科技点][BZOJ3545&BZOJ3551]克鲁斯卡尔重构树
这次我们来搞一个很新奇的知识点:克鲁斯卡尔重构树.它也是一种图,是克鲁斯卡尔算法求最小生成树的升级版首先看下面一个问题:BZOJ3545 Peaks. 在Bytemountains有N座山峰,每座山峰 ...
- Prism5.0新内容 What's New in Prism Library 5.0 for WPF(英汉对照版)
Prism 5.0 includes guidance in several new areas, resulting in new code in the Prism Library for WPF ...
- Elasticsearch 学习之 分片未分配原因
分片未分配的原因主要有: 1)INDEX_CREATED:由于创建索引的API导致未分配.2)CLUSTER_RECOVERED :由于完全集群恢复导致未分配.3)INDEX_REOPENED :由于 ...
随机推荐
- python2.7无法安装python-ldap、django-auth-ldap
1.安装报错信息: error: Microsoft Visual C++ 9.0 is required. Get it from http://aka.ms/vcpython27 或者fatal ...
- Java的初始化与清理
大家都知道,Java是站在巨人的肩上成功的,它是在C&C++的基础上进一步的开发,投入面向对象开发的怀抱.Java吸取了很多以前的教训,加入自己很多独创的方式.在程序语言发展初期,许多C程序员 ...
- SDN前瞻 网络的前世今生
本文基于SDN导论的视频而成:SDN导论 目前网络层面流行的技术概念:虚拟中心:公有云私有云:数据中心等等. SDN主要的模拟器:Mininet OpenDaylight(Cisco) ONOS(AT ...
- HDU 3435 A new Graph Game(最小费用流:有向环权值最小覆盖)
http://acm.hdu.edu.cn/showproblem.php?pid=3435 题意:有n个点和m条边,你可以删去任意条边,使得所有点在一个哈密顿路径上,路径的权值得最小. 思路: 费用 ...
- 创建maven或者Gradle项目的时候GroupId和ArtifactId以及Version是什么意思?
GroupId 是项目组织的唯一标识符,在实际开发中对应JAVA的包的结构,就是main目录里java的目录结构,如 ‘com.itcast.demo’. ArtifactId是项目的唯一标识符,在实 ...
- Ubuntu16 nginx安装http_image_filter_module模块
目录 配置image_filter 配置 重启nginx 如何安装呢? 安装image_filter模块依赖的库. 查看之前的配置 添加上图片模块[由于它是系统模块,不需要额外下载,直接添加就可以了] ...
- 何时使用MQ ?
何时使用MQmq作为一种基础中间件在互联网项目中有着大量的使用. 一种技术的产生自然是为了解决某种需求,通常来说是以下场景: 需要跨进程通信:B系统需要A系统的输出作为输入参数.当A系统的输出能力远远 ...
- bzoj1058: [ZJOI2007]报表统计 stl xjbg
小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一.经过仔细观察,小Q发现统计一张报表实际上是维护一个可能为负数的整数数列,并且 ...
- POJ 3414 dfs 回溯
题目链接:http://poj.org/problem?id=3414 题意:三个值A, B, C, A和B是两个杯子的容量,问最短操作数使A或者B里的水量是C.有三种操作. 思路:dfs.暴力 很简 ...
- easyui combotree 异步树 前端写法js
简要说下使用场景: combotree下拉框第一次加载时,请求一个接口,页面上展示顶层节点们(可以理解为最顶层的节点,比如所有的一级公司): 当点击其中一个节点前面的小三角展开时,再次请求服务器接口( ...