【洛谷 P4735】 最大异或和 (可持久化Trie)
题目链接
维护整个数列的异或前缀和和\(s\),然后每次就是要求\(s[N]\text{^}x\text{^}s[k],l-1<=k<=r-1\)的最大值
如果没有\(l\)的限制,那么直接用可持久化\(Trie\)查询第\(r\)个版本跑最大异或和就行。
\(Trie\)求最大异或值的方法就是把数看成二进制建树,一位位往下走能往相反的就往相反的走,不能就走相同的,走到底就是答案。
现在多了\(l\)的限制,所以需要记录每个节点在这个节点的子树中结尾的数的最大的编号是多少,记为\(latest\),每次限制只能走\(latest>=l-1\)的节点。
#include <cstdio>
#define re register
const int MAXN = 20000010;
inline int read(){
int s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0',ch = getchar();
return s * w;
}
int trie[MAXN][2], latest[MAXN], root[MAXN], s[MAXN];
int n, m, num;
inline int max(const int a, const int b){
return a > b ? a : b;
}
void insert(int i, int k, int p, int q){
if(k < 0){ latest[q] = i; return ; }
re int c = s[i] >> k & 1;
if(p) trie[q][c ^ 1] = trie[p][c ^ 1];
trie[q][c] = ++num;
insert(i, k - 1, trie[p][c], trie[q][c]);
latest[q] = max(latest[trie[q][0]], latest[trie[q][1]]);
}
int query(int now, int val, int k, int limit){
if(k < 0) return s[latest[now]] ^ val;
re int c = val >> k & 1;
if(latest[trie[now][c ^ 1]] >= limit) return query(trie[now][c ^ 1], val, k - 1, limit);
return query(trie[now][c], val, k - 1, limit);
}
char opt;
int main(){
n = read(); m = read();
root[0] = ++num; latest[0] = -1;
insert(0, 23, 0, root[0]);
for(re int i = 1; i <= n; ++i){
s[i] = s[i - 1] ^ read();
root[i] = ++num;
insert(i, 23, root[i - 1], root[i]);
}
for(re int i = 1, l, r, x; i <= m; ++i){
do opt = getchar(); while(opt != 'A' && opt != 'Q');
if(opt == 'A'){
x = read();
root[++n] = ++num;
s[n] = s[n - 1] ^ x;
insert(n, 23, root[n - 1], root[n]);
}
else{
l = read(); r = read(); x = read();
printf("%d\n", query(root[r - 1], s[n] ^ x, 23, l - 1));
}
}
return 0;
}
【洛谷 P4735】 最大异或和 (可持久化Trie)的更多相关文章
- 洛谷P4592 [TJOI2018]异或 【可持久化trie树】
题目链接 BZOJ4592 题解 可持久化trie树裸题 写完就A了 #include<algorithm> #include<iostream> #include<cs ...
- Bzoj3261/洛谷P4735 最大异或和(可持久化Trie)
题面 Bzoj 洛谷 题解 显然,如果让你查询整个数列的最大异或和,建一颗\(01Trie\),每给定一个\(p\),按照二进制后反方向跳就行了(比如当前二进制位为\(1\),则往\(0\)跳,反之亦 ...
- 洛谷 P4735 最大异或和 解题报告
P4735 最大异或和 题目描述 给定一个非负整数序列\(\{a\}\),初始长度为\(N\). 有\(M\)个操作,有以下两种操作类型: A x:添加操作,表示在序列末尾添加一个数\(x\),序列的 ...
- 【题解】洛谷P4735最大异或和
学习了一下可持久化trie的有关姿势~其实还挺好理解的,代码也短小精悍.重点在于查询某个历史版本的trie树上的某条边是否存在,同样我们转化到维护前缀和来实现.同可持久化线段树一样,我们为了节省空间继 ...
- [洛谷P4735]最大异或和
题目大意:有一串初始长度为$n$的序列$a$,有两种操作: $A\;x:$在序列末尾加一个数$x$ $Q\;l\;r\;x:$找一个位置$p$,满足$l\leqslant p\leqslant r$, ...
- 【洛谷P4735】最大异或和
题目大意:给定一个长度为 N 的序列,支持两个操作:在序列末尾添加一个新的数字,查询序列区间 \([l,r]\) 内使得 \(a_p\oplus a_{q+1}\oplus ... a_N\oplus ...
- 洛谷.5283.[十二省联考2019]异或粽子(可持久化Trie 堆)
LOJ 洛谷 考场上都拍上了,8:50才发现我读错了题=-= 两天都读错题...醉惹... \(Solution1\) 先求一遍前缀异或和. 假设左端点是\(i\),那么我们要在\([i,n]\)中找 ...
- 洛谷 P3359 改造异或树
题目描述 给定一棵n 个点的树,每条边上都有一个权值.现在按顺序删掉所有的n-1条边,每删掉一条边询问当前有多少条路径满足路径上所有边权值异或和为0. 输入输出格式 输入格式: 第一行一个整数n. 接 ...
- [洛谷P4592][TJOI2018]异或
题目大意:有一棵$n$个点的树,第$i$个点权值为$w_i$,有两种操作: $1\;x\;y:$询问节点$x$的子树中与$y$异或结果的最大值 $2\;x\;y\;z:$询问路径$x$到$y$上点与$ ...
随机推荐
- 开发iOS百度地图大头针可以重复点击
[self.mapView deselectAnnotation:view.annotation animated:YES];
- asp.net 后台注册(调用)JS
1.使用Page.ClientScript.RegisterClientScriptBlock 使用 Page.ClientScript.RegisterClientScriptBlock可以防止ja ...
- Thinkphp5获取数据库数据到视图
这是学习thinkhp5的基础篇笔记. 本文主要讲怎么配置数据库链接,以及查询数据库数据,并且最后将数据赋给视图. 数据库配置: thinkphp5的数据库配置默认在conf下的database.ph ...
- django 使用json.dumps转换queryset的datatime报错问题解决
最近在使用django做项目的时候想使用ajax来实现前后台数据的交互,但是在将数据库查询结果转换成json数据时,遇到时间格式的数据转换遇到问题,无法正确的进行转换,具体如下: 转换成json时使用 ...
- ManagementObjectSearcher的使用
1.获取本地路径的网络访问地址 private IEnumerable<KeyValuePair<string, string>> GetShareFolders() { va ...
- leetcode 整理
1.Two Sum 构造Comparator,KSum 这一类的问题最基本的一题, 解法: 先sort,然后双指针,头尾各一个.进行加逼找值. 对于其余的KSum最终是降次到2次. 如3Sum固定一个 ...
- Java-通过比较throw与throws来阐述抛出异常
转自:http://www.cnblogs.com/Miracle-Maker/p/6239346.html 浅谈Java异常 以前虽然知道一些异常的处理,也用过一些,但是对throw和throws区 ...
- 【.Net】浅谈C#中的值类型和引用类型
在C#中,值类型和引用类型是相当重要的两个概念,必须在设计类型的时候就决定类型实例的行为.如果在编写代码时不能理解引用类型和值类型的区别,那么将会给代码带来不必要的异常.很多人就是因为没有弄清楚这两个 ...
- 获取当前路径下的所有文件路径 :listFiles
获取当前路径下的所有文件路口 :listFiles
- 【bzoj2588】Spoj 10628. Count on a tree 离散化+主席树
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...