【可持久化0/1Trie】【P4735】最大异或和
Description
给定一个长度为 \(n\) 的序列 \(A\),有 \(m\) 次操作,每次要么在序列尾部再添加一个数,将序列长度 \(n\) 加一,要么给进行一次查询,给定查询参数 \(l,~r,~x\) 要求在 \([l,~r]\) 内找一个位置 \(p\),要求最大化 \(x~~xor ~~Xor_{i = p}^{n} A_i\)。
Limitation
\(1 \leq n,~m \leq 3 \times 10^5\)
\(0 \leq A_i \leq 10^7\)
Solution
考虑由于带加入,后缀异或和不太好维护,于是考虑维护前缀异或和 \(\{presum\}\),那么每次询问等于找一个点 \(p \in [l - 1, r)\),最大化 \(presum_p~~xor~~presum_n~~xor~~x\)。
由于 \(presum_n~~xor~~x\) 是已知的,于是问题就是查询区间内一个位置最大化该点和某个给定值的异或值。 考虑类似主席树的建树方法建立可持久化0/1Trie,在 Trie 的每个节点记录前缀该节点共有几个为 \(0\) 的孩子和为 \(1\) 的孩子,相减即可维护对应区间每个节点是否有对应孩子。
有几个需要注意的细节,首先是由于查的是前缀-1,所以允许如果 $l =1 $ 则前缀什么都不选,因此 \(presum_0\) 应插入一个 \(0\) 而不是置为空。另外注意通过查询的位置 \(x\) 是 \(p - 1\),对应相减的可持久化0/1Tire所维护的版本号应是 \(l - 2,~r - 1\)。当 \(l = 1\) 时需要特判维护版本号是 \(l - 1, r - 1\),同时如果 \(r = 1\) 则对应查询的版本号为 \(0,~0\),当然什么也查不到,应该特判这种情况。另外由于插入 \(m\) 个数,原始 \(n\) 个数,所以数组需要开 \(n + m\)
Code
卡常的题都是屑题
出卡常题的出题人都是毒瘤出题人
好吧被卡的很难受,做了一点优化。
首先是注意到无论是插入还是查询,在0/1Trie上走的路径都是一条链而不具备分叉结构,所以不需要递归只需要循环即可解决问题。但是貌似意义不大,因为递归了写的也是尾递归,貌似开了 -O2 以后会被自动优化成循环233333所以并不能解决问题
写了个内存池,这个玩意真tm有用……甩动态分配内存两条街……
然后就最慢 \(940s\) 卡着过了
#include <cstdio>
#include <algorithm>
const int maxn = 600005;
const int upceil = 25;
const int tupceil = 24;
const int maxt = maxn * upceil;
struct Tree {
Tree *ch[2];
int v[2];
Tree() { ch[0] = ch[1] = NULL; v[0] = v[1] = 0; }
};
Tree *rot[maxn], *pool[maxt], qwq[maxt];
int n, m, sum, top;
int MU[maxn];
void build(Tree *u, Tree *pre, const int v, int p);
int query(const Tree *const pre, const Tree *const u, const int v, const int p);
int main() {
freopen("1.in", "r", stdin);
qr(n); qr(m);
for (int i = 0; i < maxt; ++i) pool[i] = qwq + i;
build(rot[0] = pool[top++], NULL, 0, tupceil);
for (int i = 1, x; i <= n; ++i) {
x = 0; qr(x);
build(rot[i] = pool[top++], rot[i - 1], sum ^= x, tupceil);
}
for (int a, b, c; m; --m) {
a = 0;
do a = IPT::GetChar(); while ((a != 'A') && (a != 'Q'));
if (a == 'A') {
a = 0; qr(a);
build(rot[n + 1] = pool[top++], rot[n], sum ^= a, tupceil);
++n;
} else {
a = b = c = 0; qr(a); qr(b); qr(c);
if (b == 1) {
qw(sum ^ c, '\n', true);
continue;
}
qw(query(rot[std::max(0, a - 2)], rot[b - 1], sum ^ c, tupceil) ^ sum ^ c, '\n', true);
}
}
return 0;
}
void build(Tree *u, Tree *pre, const int v, int p) {
while (~p) {
if (pre) *u = *pre;
int x = (v & (1 << p)) >> p;
++u->v[x];
u = u->ch[x] = pool[top++];
if (pre) pre = pre->ch[x];
--p;
}
}
int query(const Tree *pre, const Tree *u, const int v, int p) {
int _ret = 0;
while (~p) {
int x = ((v & (1 << p)) >> p) ^ 1, y = u->v[x] - (pre ? pre->v[x] : 0);
if (!y) x ^= 1;
_ret |= (x << p);
u = u->ch[x];
if (pre) pre = pre->ch[x];
--p;
}
return _ret;
}
【可持久化0/1Trie】【P4735】最大异或和的更多相关文章
- 洛谷 P4735 最大异或和 解题报告
P4735 最大异或和 题目描述 给定一个非负整数序列\(\{a\}\),初始长度为\(N\). 有\(M\)个操作,有以下两种操作类型: A x:添加操作,表示在序列末尾添加一个数\(x\),序列的 ...
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (0/1-Trie树)
Vasiliy's Multiset 题目链接: http://codeforces.com/contest/706/problem/D Description Author has gone out ...
- Bzoj3261/洛谷P4735 最大异或和(可持久化Trie)
题面 Bzoj 洛谷 题解 显然,如果让你查询整个数列的最大异或和,建一颗\(01Trie\),每给定一个\(p\),按照二进制后反方向跳就行了(比如当前二进制位为\(1\),则往\(0\)跳,反之亦 ...
- P4735 最大异或和 /【模板】可持久化Trie
//tire的可持久化 //线段树的可持久化——主席树 //可持久化的前提:本身的拓扑结构在操作时不变 //可以存下来数据结构的所有历史版本 //核心思想:只记录每一个版本与前一个版本不一样的地方 / ...
- 可持久化+Trie || BZOJ 3261最大异或和 || Luogu P4735 最大异或和
题面:最大异或和 代码: #include<cstdio> #include<cstring> #include<iostream> using namespace ...
- luogu P4735 最大异或和
嘟嘟嘟 省选竟然考了一个可持久化trie,就挑着我不会的考. 话说考场上我确实写了一个trie的做法,只不过一直没调出来然后就只剩暴力分了. 现在想想实在是太蠢了,明明对算法没有把握,却头脑一热在这题 ...
- 51Nod - 1295:XOR key (可持久化Trie求区间最大异或)
给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求ALL 至 ARR 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值 ...
- P4735 最大异或和 01 Trie
题目描述 给定一个非负整数序列 \(\{a\}\),初始长度为\(n\). 有 \(m\) 个操作,有以下两种操作类型: \(A\ x\):添加操作,表示在序列末尾添加一个数 \(x\),序列的长度 ...
- 【题解】洛谷P4735最大异或和
学习了一下可持久化trie的有关姿势~其实还挺好理解的,代码也短小精悍.重点在于查询某个历史版本的trie树上的某条边是否存在,同样我们转化到维护前缀和来实现.同可持久化线段树一样,我们为了节省空间继 ...
随机推荐
- Asp.Net页面刷新防止跳转到其他浏览器或新的选项卡
前端页面js代码: <head> <script> window.name = "PremaritalCheckup_ManSocietyAgreeForm" ...
- 深入浅出JVM之垃圾收集算法
判断哪些对象需要被回收 引用计数算法: 给对象中添加一个引用计数器,每当有一个地方引用时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的. 但是JVM没有使 ...
- Spring扩展点之FactoryBean接口
前言 首先看一下接口定义 public interface FactoryBean<T> { /** * 返回对象实例 */ @Nullable T getObject() throws ...
- 配置Java,jdk环境变量
注意:所有的都是配系统变量 变量名:JAVA_HOME 变量值:D:\Program Files\Java\jdk1.8.0_202(以自己的为准)变量名:Path 变量值:%JAVA_HOME%\b ...
- App过大
最近开发中遇到一个报错信息 如下 Error:Cannot fit requested classes in a single dex file.Try supplying a main-dex li ...
- Spark调用Linux命令实现解压和压缩功能
一.应用场景 在Spark程序中调用Linux命令,实现一些程序难以实现的功能,例如:发送模拟邮件.文件打包或解压等等 二.代码实现 package big.data.analyse.linux im ...
- Spark GraphX图计算简单案例【代码实现,源码分析】
一.简介 参考:https://www.cnblogs.com/yszd/p/10186556.html 二.代码实现 package big.data.analyse.graphx import o ...
- Excel分列,Excel 列拆分,Excel根据分隔符号拆分某列
解决方案: https://zhidao.baidu.com/question/572807483.html 步骤:数据--分列--下一步--其它---下一步-- 注意的此操作会覆盖当前列和后n列(根 ...
- “GIS DICTIONARY A-Z” 查询页面开发(2)——INSERT INTO数据库
今日工作:数据库连接.数据写入 一.数据库连接:使用了pymysql库 from G2_dataClean import defList import pymysql db = pymysql.con ...
- python_机器学习(一)、基本概念
机器学习基础知识: (一).什么是机器学习? 对于某给定的任务T, 在合理的性能调度方案P的前提下, 某计算机程序可以自主学习任务T的经验E, 随着提供合适.优质.大量的经验E, 该程序任务T的性能逐 ...