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树、求最大区间异或和)相关推荐

  1. BZOJ 3261 最大异或和 可持久化Trie树

    题目大意:给定一个序列,提供下列操作: 1.在数组结尾插入一个数 2.给定l,r,x,求一个l<=p<=r,使x^a[p]^a[p+1]^...^a[n]最大 首先我们能够维护前缀和 然后 ...

  2. 【bzoj3261】最大异或和 可持久化Trie树

    题目描述 给定一个非负整数序列 {a},初始长度为 N.        有M个操作,有以下两种操作类型: 1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1. 2.Q l r x: ...

  3. BZOJ3261: 最大异或和(可持久化trie树)

    题意 题目链接 Sol 设\(sum[i]\)表示\(1 - i\)的异或和 首先把每个询问的\(x \oplus sum[n]\)就变成了询问前缀最大值 可持久化Trie树维护前缀xor,建树的时候 ...

  4. P4735 最大异或和 可持久化trie树

    可持久化01trie类似主席树思想    但是不支持版本差(也可以加一个siz 做差)    只能再维护一个左端点的最大值即可 #include<bits/stdc++.h> using ...

  5. BZOJ.3261.最大异或和(可持久化Trie)

    题目链接 这个每次修改后缀好像很难搞,但是因为异或可以抵消,求sum[p~n]的最大值可以转化为求sum[1~n] xor sum[1~p-1]的最大值. \(p-1\in [l-1,r-1]\),用 ...

  6. BZOJ3261 最大异或和 解题报告(可持久化Trie树)

    本题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3261 题目描述 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类 ...

  7. HDU - 4757 Tree(LCA+可持久化trie树)

    题目链接:点击查看 题目大意:给出一棵有有n个节点的树,每个点都有一个权值,现在给出m个查询,每次查询的形式为:x,y,z,求出从点x到点y的路径上任选一点,使其与z的异或值最大,输出异或值 题目分析 ...

  8. BZOJ #3166. [Heoi2013]Alo(可持久化trie树+set)

    #3166. [Heoi2013]Alo description solution code BZOJ3166 description Welcome to ALO ( Arithmetic and ...

  9. P4735 最大异或和 01可持久化Trie树模板

    原题:https://www.luogu.org/problemnew/show/P4735 题解:观察一下式子,将a数组求一个异或前缀和,其实就是s[n]^x^s[p-1]的最大值 p∈[l,r], ...

最新文章

  1. 研发流程在敏捷开发中的详解
  2. 用户空间与内核空间数据交换的方式(zz)
  3. 【DIY】最简单粗暴便宜的DIY定时器方法,没有之一
  4. (整理)用户空间_内核空间以及内存映射
  5. JDBC详解系列之流程
  6. 【详细分析】1023 Have Fun with Numbers (20 分)_20行代码AC
  7. python bokeh_提升视觉效果:使用Python和Bokeh制作交互式地图
  8. markdown改字体和背景颜色(html)
  9. tensorflow has no attribute logging
  10. Android开发笔记(五十七)录像录音与播放
  11. myEclipse-svn的安装使用
  12. 在IntelliJ IDEA中使用 JAVAFX 过程记录
  13. 标准盒子模型和IE盒子模型
  14. IDEA与VsCode两种开发工具的比较
  15. 几款主流数据库的详细比较
  16. android zooming bitmap
  17. 微信小程序php开发实例,微信小程序教程之demo:猫眼电影实例
  18. 技能篇:开发必备linux命令大全
  19. Shader学习的基础知识( 三十一)水波效果
  20. 解决MPS运行中出现Unsupported major.minor version错误问题

热门文章

  1. 这5种动态炫酷图,用Python就可以画!
  2. 图像处理分类、一般流程与算法
  3. 一次搞定OpenCV源码及扩展模块的编译与环境配置
  4. 使用Python+OpenCV+yolov5实现行人目标检测
  5. shell编程系列7--shell中常用的工具find、locate、which、whereis
  6. Ubuntu 64bit 安装 ulipad4.1
  7. [转]ASP.NET页面生命周期描述
  8. 字体在ppt中可以整体替换吗_干货,做PPT时这样选择字体,瞬间提升幻灯片档次,看完你就懂了...
  9. miniui文件上传 linux,MINIUI grid学习笔记
  10. vue 怎么在字符串中指定位置插入字符_Vue数组变更方法