bzoj 3261
题目描述:这里
可持久化字典树裸题,可以作为模板使用
首先介绍一下可持久化字典树
可持久化字典树,顾名思义,就是一种可持久化的数据结构,常用于处理异或问题
我们看一下题目,发现要求一个最大异或和,但是这个最大异或和很特殊,有一个区间的限制
首先,对于异或和问题,我们一般利用异或的前缀和性质,把一个区间的异或和变成两个值的异或
于是问题就转化为,在[l,r]区间内求一个位置y,使$s_y xor s_n xor x$值最大
然后分析一下,不难想到,对于一般的最大异或问题,我们可以用01trie解决
但是此题中有区间限制,所以一般的01trie就难以使用了
这样我们引入可持久化字典树
可持久化字典树与普通字典树最大区别就在于,每次不是在原字典树上插入新的字符串,而是重建一棵字典树,然后将没有改变的信息与上一棵树共享
(也就是主席树的思想哈)
那么,在这里我们就构造一棵可持久化字典树(构造过程见代码,与主席树十分类似),然后进行查询即可
查询时,我们将$sn xor x$当成整体进行查询,然后像在正常的01trie上从高位向低位查找,首先查找这一位上是否可以放上不同的数,这里很好办,只需要在r和l-1上作差即可
这样就结束了
还有一个要点:对于异或和类的问题,我们要在将原序列整体右移一位,然后在空出来的首位补一个0!!!
为什么?
我们查询的是区间[l,r],而我们知道,$s[n]^s[m]$代表的是[m+1,n]的异或和!
所以,当我们把问题转化为求两个数的异或最大值时,我们事实上也应该把区间改成[l-1,r-1]!
可是,如果我们把询问区间改成了[l-1,r-1],我们在计算的时候,实际应当用的是[l-2,r-1]!
这又是为什么?
因为我们在计算时,计算方法是用区间右端点减区间左端点,可区间左端点也在区间内啊!
因此我们实际应该将左端点再向左移一位
可是哪有那么多位可移啊!万一给的l是1呢?
所以我们在首位补一个,这样就能保证查找时的正确性了。
贴代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
struct Trie
{
int to[];
int ed;
}tree[];
int s[];
int rt[];
int n,m;
int tot=;
char ch[];
void ins(int x,int num,int las)
{
rt[num]=++tot;
int now=rt[num],last=rt[las];
for(int i=;i>=;i--)
{
tree[now].to[]=tree[last].to[];
tree[now].to[]=tree[last].to[];
tree[now].ed=tree[last].ed+;
if((<<i)&x)tree[now].to[]=++tot,now=tree[now].to[],last=tree[last].to[];
else tree[now].to[]=++tot,now=tree[now].to[],last=tree[last].to[];
}
tree[now].ed=tree[last].ed+;
}
int query(int lq,int rq,int x)
{
int ret=;
int l=rt[lq],r=rt[rq];
for(int i=;i>=;i--)
{
if(x&(<<i))
{
if(tree[tree[r].to[]].ed-tree[tree[l].to[]].ed)ret|=(<<i),l=tree[l].to[],r=tree[r].to[];
else l=tree[l].to[],r=tree[r].to[];
}else
{
if(tree[tree[r].to[]].ed-tree[tree[l].to[]].ed)ret|=(<<i),l=tree[l].to[],r=tree[r].to[];
else l=tree[l].to[],r=tree[r].to[];
}
}
return ret;
}
int main()
{
scanf("%d%d",&n,&m);
n++;
ins(,,);
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
s[i]=s[i-]^x;
ins(s[i],i,i-);
}
for(int i=;i<=m;i++)
{
scanf("%s",ch);
if(ch[]=='A')
{
int x;
scanf("%d",&x);
n++;
s[n]=s[n-]^x;
ins(s[n],n,n-);
}else
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
int s1=x^s[n];
printf("%d\n",query(l-,r,s1));
}
}
return ;
}
bzoj 3261的更多相关文章
- BZOJ 3261: 最大异或和
Description 一个序列,支持两个操作. 1.在序列尾加入一个数. 2.询问 [l,r] 中与 x 异或值最大的数. \(n\leqslant 3*10^5\) Sol 可持久化 Trie 树 ...
- BZOJ 3261: 最大异或和( 可持久化trie )
搞成前缀和然后就可以很方便地用可持久化trie维护了.时间复杂度O((N+M)*25) -------------------------------------------------------- ...
- bzoj 3261: 最大异或和 (可持久化trie树)
3261: 最大异或和 Time Limit: 10 Sec Memory Limit: 512 MB Description 给定一个非负整数序列 {a},初始长度为 N. ...
- BZOJ 3261: 最大异或和位置-贪心+可持久化01Trie树
3261: 最大异或和 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3519 Solved: 1493[Submit][Status][Discu ...
- bzoj 3261最大异或和
Description 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类型: 1.Ax:添加操作,表示在序列末尾添加一个数x,序列的长度N+1. 2.Qlrx:询问操作,你需要 ...
- BZOJ 3261 最大异或和(算竞进阶习题)
可持久化Trie 需要知道一个异或的特点,和前缀和差不多 a[p] xor a[p+1] xor....xor a[n] xor x = a[p-1] xor a[n] xor x 所以我们把a[1. ...
- 【BZOJ 3261】最大异或和【可持久化字典树】
题意 给出一个长度为n的整数序列,给出m个操作.操作有两种.1,Ax表示在序列结尾增加x.2,Qlrx表示找到一个位置p满足 l<=p<=r,使得a[p] xor a[p+1]xor... ...
- bzoj 3261 最大异或和 可持久化字典树(01树)
题目传送门 思路: 由异或的性质可得,题目要求的式子可以转化成求$max(pre[n]^x^pre[i])$,$pre[i]$表示前缀异或和,那么我们现在就要求出这个东西,所以用可持久化字典树来求,每 ...
- BZOJ 3261 最大异或和 可持久化Trie树
题目大意:给定一个序列,提供下列操作: 1.在数组结尾插入一个数 2.给定l,r,x,求一个l<=p<=r,使x^a[p]^a[p+1]^...^a[n]最大 首先我们能够维护前缀和 然后 ...
随机推荐
- 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) - 4.28
赛后补了几道 赛中我就写了两个... A - Altruistic AmphibiansGym - 101933A 看了眼榜没几个人做.就没看. 最后发现就是一个DP(但是我觉得复杂度有点迷) 题意: ...
- 大白话 Scala 控制抽象
2019-04-14 关键字: Scala.Scala控制抽象.Scala高阶函数 本篇文章系笔者根据当前掌握的知识对 Scala 控制抽象的教材知识总结,不保证文章所述内容的绝对.完全正确性. 在 ...
- [SCOI2009]生日礼物题解
题目 一道模拟和队列题,但模拟比队列的成分多一些.队列也就是用两个指针模拟的. 可以用枚举的思想.首先我们知道r(即区间的右端点是肯定不会左移的),而l右移的同时,r可能不变,也可能右移,所以这样就可 ...
- awk 计算某一列的和
awk 计算某一列的和 我需要通过nova list 显示所有虚拟机的cpu总和,即用awk计算某一列的综合 [root@control01 ~]# nla | awk -F '|' 'BEGIN{s ...
- HIS(LIS、PACS、RIS、EMR)系统简介
HIS(LIS.PACS.RIS.EMR)系统简介 HIS:医院信息系统(Hospital Information System, HIS),利用电子计算机和通讯设备,为医院所属各部 门提供病人诊疗信 ...
- 《Java》第八周学习总结
第八周学习内容:课本第15章节的内容泛型与集合框架 主要内容有 -泛型-链表-堆栈-散列映射-树集-树映射 重点和难点-重点:泛型和集合的使用码云:https://gitee.com/ShengHu ...
- js数字串传参时变科学计数法
例1:onclick=channel_info_listFt(\"'+val.gid+'\",'+val.deviceIdOwner+','+val.gname+') 当长度过长的 ...
- java 中final关键字
1.final变量,一旦该变量被设定,就不可以再改变该变量的值. final关键字定义的变量必须声明时赋值.一旦一个对象引用被修饰为final后,它只能恒定指向一个对象,一个既是static和fina ...
- centos7 安装软件指南
1. 安装Scrapy: 首先确保依赖已经安装: yum groupinstall -y development tools yum install -y epel-release libxslt-d ...
- Python文本编辑器推荐
首推当然是Sublime Text:可以中文化,百度上面有教程,页面比较酷炫,功能也不错 然后就是Notepad++,台湾开发,有中文界面