Trie树是字符串问题中应用极为广泛的一种数据结构,可以拓展出AC自动机、后缀字典树等实用数据结构。

然而在此我们考虑0-1 Trie的应用,即在序列最大异或问题中的应用。

这里的异或是指按位异或。按位异或有很多重要的性质。比如可拆分性,每个位可以进行单独处理后线性合并得到最终结果。

同时按位异或也是可减的。比如0111 ^ 1010 = 1101, 那么 1101 ^ 1010 = 0111. 证明从略。


首先我们考虑0-1 Trie的版本,也就是

给定一个序列a[i], 每次询问一个数x与a[i]中各元素能得到的按位异或的最大值。

暴力自然是O(n^2)的。但是我们想到之前的可拆分性,是否能将每个位单独考虑?但是,第一位的选择又会限定第二位的选择范围。即选择第一位是0或1后,第二位的选择就不能从a[i]中的所有元素中进行选择,而要将a[i]分为两份。我们很容易发现这是一个类似树形的问题,所以我们考虑使用树形数据结构。而鉴于多个串根据前缀进行选择性划分的特点,我们使用Trie树来从高位到低位地维护这些0-1串,即0-1 Trie。

注意到这种从高位到低位的选择一定是全局最优的。也就是说,对于异或结果,从高到低考虑,每一位能设成1就设成1. 证明可以利用反证法。

这样我们就利用一个贪心完成了这样的事情。这样的处理是O(n+m)的(常数有32倍)


什么时候需要使用可持久化0-1 Trie呢?我们想,在使用可持久化线段树维护区间K大值得时候,可持久化是否起到了限定区间的作用?同理,在这里,我们也是用可持久化来实现区间的限定。

重要性质:Trie树的节点存在性满足可减性。

我们可以把节点的存在性记录改为节点的数目记录,这样用root[r]中某节点的数目减去root[l-1]中某节点的数目,就可以得到区间中是否存在某个节点。


 #include<bits/stdc++.h>
using namespace std; int ch[][],val[],cnt[],root[],ts[],ind,n,m; void insert(int p,int p0,int dep) {
ch[p][]=ch[p0][];
ch[p][]=ch[p0][];
if(dep==) return;
if(ch[p0][ts[dep+]]==) {
ch[p][ts[dep+]]=++ind;
val[ind]=ts[dep+];
cnt[ind]=;
insert(ind,ch[p0][ts[dep+]],dep+);
}
else {
ch[p][ts[dep+]]=++ind;
val[ind]=ts[dep+];
cnt[ch[p][ts[dep+]]]=cnt[ch[p0][ts[dep+]]]+;
insert(ch[p][ts[dep+]],ch[p0][ts[dep+]],dep+);
}
} void trie_insert(int rtx,int num) {
for(int i=;i<=;i++)
ts[i]=(num>>(-i))&;
insert(root[rtx],root[rtx-],);
} int xormax(int rtx,int rty,int num) {
int p=root[rtx], q=root[rty], ans=;
for(int i=;i>=;i--) {
if((num>>i)&) {
if(cnt[ch[q][]]-cnt[ch[p][]]) ans=ans*+, p=ch[p][], q=ch[q][];
else ans=ans*, p=ch[p][], q=ch[q][];
}
else {
if(cnt[ch[q][]]-cnt[ch[p][]]) ans=ans*+, p=ch[p][], q=ch[q][];
else ans=ans*, p=ch[p][], q=ch[q][];
}
}
return ans;
} int main() {
cin>>n;
for(int i=;i<=n;i++) {
int t;
cin>>t;
root[i]=++ind;
trie_insert(i,t);
}
cin>>m;
for(int i=;i<=m;i++) {
int t1,t2,t3;
cin>>t1>>t2>>t3;
t1--;
cout<<xormax(t1,t2,t3)<<endl;
}
}

可持久化0-1 Trie 简介的更多相关文章

  1. Trie 简介

    一.Trie简介 在计算机科学中,Trie,又称字典树.前缀树.单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎 ...

  2. 【可持久化0/1Trie】【P4735】最大异或和

    Description 给定一个长度为 \(n\) 的序列 \(A\),有 \(m\) 次操作,每次要么在序列尾部再添加一个数,将序列长度 \(n\) 加一,要么给进行一次查询,给定查询参数 \(l, ...

  3. Apache Flume 1.7.0 各个模块简介

    Flume简介 Apache Flume是一个分布式.可靠.高可用的日志收集系统,支持各种各样的数据来源,如http,log文件,jms,监听端口数据等等,能将这些数据源的海量日志数据进行高效收集.聚 ...

  4. 0.ECMAScript 6 简介

    ECMAScript 6简介 ECMAScript 6 简介 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了.它的目 ...

  5. HDU4825:Xor Sum 解题报告(0/1 Trie树)

    Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数. 随后 Prometheus 将向 Ze ...

  6. Libevent:0异步IO简介

    一:异步IO简介 大多数的初级编程者都是从阻塞IO调用开始网络编程的.阻塞(同步)IO调用指的是:调用会一直阻塞,不会返回,直到发生下面两种情况之一.要么操作完成,要么经历相当长的时间,网络协议栈自己 ...

  7. Linux Kernel 0.12 启动简介,调试记录(Ubuntu1804, Bochs, gdb)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  8. zabbix 3.0快速安装简介(centos 6)

    zabbix快速安装 系统版本:centos 6 1.yum源配置和zabbix.msyql安装 rpm -ivh http://mirrors.aliyun.com/zabbix/zabbix/3. ...

  9. zabbix 3.0快速安装简介(centos 7)

    zabbix快速安装 系统版本:centos 7 通过yum方法安装Zabbix3.0,安装源为阿里云 yum源配置 rpm -ivh http://mirrors.aliyun.com/zabbix ...

随机推荐

  1. Dart中类的getter和setter

    Dart类Getters和Setter Getters和Setter(也称为访问器和更改器)允许程序分别初始化和检索类字段的值. 使用get关键字定义getter或访问器.Setter或存取器是使用s ...

  2. java多线程技能-使用多线程-继承Thread类

    /* 使用多线程可通过继承Thread类或实现Runnable接口. Thread和Runnable的关系:public class Thread implements Runnable. 使用thr ...

  3. phpcms搜索给分页代码添加参数方法

    在使用PHPCMS开发网站时遇到了一个搜索功能,需要在搜索结果分页链接上添加一些传递的参数,不然不能够正确翻页. 方法: 找到\phpcms\libs\functions\global.func.ph ...

  4. MySQL 8 服务器组件

    MySQL 服务器包含了一个基于组件的架构,用于扩展服务器功能.服务器和其他组件可以使用组件提供的服务.(在使用服务方面,服务器也是一个组件,等同于其他组件).组件之间交互仅通过他们各自提供的服务. ...

  5. ffmpeg基本功能使用

    任务描述:由给定图像序列合成 24fps 视频 方案一 直接对图像进行操作,适用于图像名比较规范且默认即为所需顺序 ffmpeg -f image2 -i ./images_crop_%d.png - ...

  6. Spring Cloud feign使用okhttp3

    指南 maven <dependency> <groupId>io.github.openfeign</groupId> <artifactId>fei ...

  7. 谷歌浏览器chrome应用商店无法打开的解决方法

    解决办法:谷歌访问助手 谷歌访问助手是一款免费的谷歌服务代理插件,不用配置就可以正常访问谷歌的大部分服务,而且速度也很快.下载地址:http://www.cnplugins.com/advsearch ...

  8. ElementUI的Table表格添加自定义头CheckBox多选框

    在ElmentUI的Table表格组件中,也许你会使用type为selection值的多选框功能,但是此时设置的label属性不生效,不能设置标题名称:有时候我们的需求就是要添加标题名称,那该如何处理 ...

  9. vue中的this.$nextTick()使用

    首先我们来翻译一下nextTick是什么意思:下一个刻度 再来看看vue官网怎么说的: Vue.nextTick( [callback, context] )在下次 DOM 更新循环结束之后执行延迟回 ...

  10. tomcat-embeded-core源码编译

    使用spring-boot创建web工程时,默认采用embeded tomcat作为容器,实际使用过程中,可能会需要对其中的某些功能做微调,而tomcat又没有给出预留配 ,这时就需要对tomcat- ...