P4735 最大异或和(可持久化trie树、求最大区间异或和)
P4735 最大异或和
我们维护一个前缀异或和:s[i]=a[1]xora[2]xor…a[i−1]xora[i]s[i] = a[1] \ xor\ a[2]\ xor\ … a[i-1] \ xor\ a[i]s[i]=a[1] xor a[2] xor …a[i−1] xor a[i]
则a[p]xora[p+1]xor…xora[N]xorxa[p]\ xor\ a[p+1]\ xor\ …\ xor\ a[N]\ xor\ xa[p] xor a[p+1] xor … xor a[N] xor x 就相当于 s[N]xorxxors[p−1]s[N] \ xor\ x\ xor\ s[p-1]s[N] xor x xor s[p−1]。
这样S[N]xorxS[N] \ xor\ xS[N] xor x就是一个定值valvalval,则相当于求一个 ppp 满足l−1<=p−1<=r−1l-1 <= p-1 <= r-1l−1<=p−1<=r−1 使得 valxors[p]val \ xor\ s[p]val xor s[p] 值最大。
因为是异或运算,我们可以利用 “最大异或对” 这道题的一些性质,使用 trietrietrie 树。我们维护前缀异或和,找到一个 ppp ,贪心地使得s[p]s[p]s[p]的二进制最高位开始到最低位的每一个数字都尽量与 valvalval 的二进制对应位相反(相同为0不同为1)
前缀异或和的每个版本都可以用持久化的 trietrietrie 记录下来。
对持久化 trietrietrie 的每个节点额外维护一个信息 max_idmax\_idmax_id ,表示其所属的最大的持久化版本,显然一个节点的 max_idmax\_idmax_id 等于其子节点中最大的版本号(因为子节点要么是连向之前的版本,要么创建了该节点后再创建子节点)。
因为要满足边界性所以要用可持久化trie树的保存历史版本来界定边界
- 边界[l−1,r−1][l-1, r-1][l−1,r−1] 判断:
如果一个节点的 max_idmax\_idmax_id 小于 l−1l-1l−1 ,说明这个节点是 s[l−1]s[l-1]s[l−1] 插入之前就已经创建出来的节点,不应该考虑在内。
对持久化树的某一个版本的根节点开始往下访问,所能访问到的节点的版本不会超过该根节点的版本,所以该题只需要从 r−1r-1r−1 版本开始访问即可满足取到的 ppp 小于等于 r−1r-1r−1。
//trie树维护的是前缀异或和的二进制01串
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 500007, M = N * 25;
/*
template<typename T>inline T read(T &x)
{x=0;ll f=1;char c;while(!isdigit(c=getchar()))if(c=='-')f=-1;while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return x*f;
}
*/
int n, m;
int sum[N];
int tr[M][2], max_id[M];
int root[N], idx;
//当前的区间位置(到时候[L,R]对比的就是这里的i)k表示当前是第几位,一共23位2^23,越高越大
void insert(int i, int k, int p, int q){//p上一个版本q下一个版本if(k < 0){max_id[q] = i;return ;}int v = sum[i] >> k & 1;if(p)//如果上个版本的当前结点是有东西的就继承一下tr[q][v ^ 1] = tr[p][v ^ 1];tr[q][v] = ++ idx;insert(i, k - 1, tr[p][v], tr[q][v]);max_id[q] = max(max_id[tr[q][0]], max_id[tr[q][1]]);
}int query(int root, int C, int L){int p = root;for(int i = 23;i >= 0;i -- ){int v = C >> i & 1;//如果版本小于L-1,说明这个节点是s[l-1]插入之前就已经创建出来的节点,不应该考虑在内if(max_id[tr[p][v ^ 1]] >= L)//如果与当前这一位相反的数存在并且该数的位置在范围以内(求异或相反为1更大)p = tr[p][v ^ 1];else p = tr[p][v];}return C ^ sum[max_id[p]];
}int main(){scanf("%d%d", &n, &m);max_id[0] = -1;//因为id从0开始这里要取一个更小的root[0] = ++ idx;insert(0, 23, 0, root[0]);for(int i = 1;i <= n; ++ i){int x;scanf("%d", &x);sum[i] = sum[i - 1] ^ x;//前缀异或和root[i] = ++ idx;insert(i, 23, root[i - 1], root[i]);//可持久化都是跟上一个版本比较}char op[2];int l, r, x;while(m -- ){scanf("%s", op);if(*op == 'A'){scanf("%d", &x);n ++ ;sum[n] = sum[n - 1] ^ x;root[n] = ++ idx;insert(n, 23, root[n - 1], root[n]);}else {scanf("%d%d%d", &l, &r, &x);//l<=p<=r,所以要查询r-1版本的printf("%d\n", query(root[r - 1], sum[n] ^ x, l - 1));}}
}
P4735 最大异或和(可持久化trie树、求最大区间异或和)相关推荐
- BZOJ 3261 最大异或和 可持久化Trie树
题目大意:给定一个序列,提供下列操作: 1.在数组结尾插入一个数 2.给定l,r,x,求一个l<=p<=r,使x^a[p]^a[p+1]^...^a[n]最大 首先我们能够维护前缀和 然后 ...
- 【bzoj3261】最大异或和 可持久化Trie树
题目描述 给定一个非负整数序列 {a},初始长度为 N. 有M个操作,有以下两种操作类型: 1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1. 2.Q l r x: ...
- BZOJ3261: 最大异或和(可持久化trie树)
题意 题目链接 Sol 设\(sum[i]\)表示\(1 - i\)的异或和 首先把每个询问的\(x \oplus sum[n]\)就变成了询问前缀最大值 可持久化Trie树维护前缀xor,建树的时候 ...
- P4735 最大异或和 可持久化trie树
可持久化01trie类似主席树思想 但是不支持版本差(也可以加一个siz 做差) 只能再维护一个左端点的最大值即可 #include<bits/stdc++.h> using ...
- BZOJ.3261.最大异或和(可持久化Trie)
题目链接 这个每次修改后缀好像很难搞,但是因为异或可以抵消,求sum[p~n]的最大值可以转化为求sum[1~n] xor sum[1~p-1]的最大值. \(p-1\in [l-1,r-1]\),用 ...
- BZOJ3261 最大异或和 解题报告(可持久化Trie树)
本题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3261 题目描述 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类 ...
- HDU - 4757 Tree(LCA+可持久化trie树)
题目链接:点击查看 题目大意:给出一棵有有n个节点的树,每个点都有一个权值,现在给出m个查询,每次查询的形式为:x,y,z,求出从点x到点y的路径上任选一点,使其与z的异或值最大,输出异或值 题目分析 ...
- BZOJ #3166. [Heoi2013]Alo(可持久化trie树+set)
#3166. [Heoi2013]Alo description solution code BZOJ3166 description Welcome to ALO ( Arithmetic and ...
- P4735 最大异或和 01可持久化Trie树模板
原题:https://www.luogu.org/problemnew/show/P4735 题解:观察一下式子,将a数组求一个异或前缀和,其实就是s[n]^x^s[p-1]的最大值 p∈[l,r], ...
最新文章
- 研发流程在敏捷开发中的详解
- 用户空间与内核空间数据交换的方式(zz)
- 【DIY】最简单粗暴便宜的DIY定时器方法,没有之一
- (整理)用户空间_内核空间以及内存映射
- JDBC详解系列之流程
- 【详细分析】1023 Have Fun with Numbers (20 分)_20行代码AC
- python bokeh_提升视觉效果:使用Python和Bokeh制作交互式地图
- markdown改字体和背景颜色(html)
- tensorflow has no attribute logging
- Android开发笔记(五十七)录像录音与播放
- myEclipse-svn的安装使用
- 在IntelliJ IDEA中使用 JAVAFX 过程记录
- 标准盒子模型和IE盒子模型
- IDEA与VsCode两种开发工具的比较
- 几款主流数据库的详细比较
- android zooming bitmap
- 微信小程序php开发实例,微信小程序教程之demo:猫眼电影实例
- 技能篇:开发必备linux命令大全
- Shader学习的基础知识( 三十一)水波效果
- 解决MPS运行中出现Unsupported major.minor version错误问题
热门文章
- 这5种动态炫酷图,用Python就可以画!
- 图像处理分类、一般流程与算法
- 一次搞定OpenCV源码及扩展模块的编译与环境配置
- 使用Python+OpenCV+yolov5实现行人目标检测
- shell编程系列7--shell中常用的工具find、locate、which、whereis
- Ubuntu 64bit 安装 ulipad4.1
- [转]ASP.NET页面生命周期描述
- 字体在ppt中可以整体替换吗_干货,做PPT时这样选择字体,瞬间提升幻灯片档次,看完你就懂了...
- miniui文件上传 linux,MINIUI grid学习笔记
- vue 怎么在字符串中指定位置插入字符_Vue数组变更方法