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;
}

最新文章

  1. EF Code First学习系列
  2. ComboBox(下拉列表框)实现省、市、县三级联动,用hibernate连接数据库
  3. primefaces 通过selectOneMenu更新显示隐藏区域
  4. php预定义常量$_SERVER
  5. 【freemaker】之自定义指令&lt;#macro&gt;
  6. angular源码分析 摘抄 王大鹏 博客 directive指令及系列
  7. 【POJ3468】【zkw线段树】A Simple Problem with Integers
  8. JS生成不重复随机数
  9. 转: 深入理解 AngularJS 的 Scope
  10. Linux系统操作指令汇总
  11. Django之Model进阶的更多操作
  12. VSCode插件开发全攻略(八)代码片段、设置、自定义欢迎页
  13. Tensorflow object detection API 搭建物体识别模型(三)
  14. Eclipse中部署Android开发环境插件安装问题方案
  15. open-falcon ---客户机agent操作
  16. Mysql逻辑分层、存储引擎
  17. MySql数据库表设计规范
  18. Linux --- vim 安装、支持python3的配置、插件自动补全YCM的安装配置及全过程错误总结
  19. 【RedHat Linux】 链路聚合
  20. 使用httpClient调用接口,参数用map封装或者使用JSON参数,并转换返回结果

热门文章

  1. FormData使用详解
  2. Redis(一) redis安装、启停
  3. 24个Jvm面试题总结及答案
  4. 两道JVM面试题,竟让我回忆起了中学时代!
  5. vue中如果在页面中v-model的是字典,那么在定义字典的时候,需要明确定义键值为&#39;&#39;或者[],否则给字典的键值赋值后页面不显示
  6. 设计模式之(十一)代理模式(Proxy)
  7. Width Height -- (1)
  8. vue+element省市县的二级联动功能
  9. 基于Netty的IdleStateHandler实现Mqtt心跳
  10. js 字符串 有没有 像C# @ 那种 换行也可以显示的方法 \