题目描述

给定一个非负整数序列 \(\{a\}\),初始长度为\(n\)。

有 \(m\) 个操作,有以下两种操作类型:

\(A\ x\):添加操作,表示在序列末尾添加一个数 \(x\),序列的长度 \(n+1\)。

\(Q\ l\ r\ x\):询问操作,你需要找到一个位置 \(p\),满足\(l \le p \le r\),使得: \(a[p] \oplus a[p+1] \oplus ... \oplus a[N] \oplus x\)最大,输出最大是多少。

输入格式

第一行包含两个整数 \(N,M\),含义如问题描述所示。

第二行包含 \(N\)个非负整数,表示初始的序列 \(A\) 。

接下来 \(M\) 行,每行描述一个操作,格式如题面所述。

输出格式

假设询问操作有 \(T\) 个,则输出应该有 \(T\) 行,每行一个整数表示询问的答案。

输入输出样例

输入 #1

5 5

2 6 4 3 6

A 1

Q 3 5 4

A 4

Q 5 7 0

Q 3 6 6

输出 #1

4

5

6

说明/提示

对于测试点 \(1−2\),\(N,M \le 5\)。

对于测试点 \(3−7\),\(N,M \le 80000\)。

对于测试点 \(8−10\),\(N,M \le 300000\)。

其中测试点 \(1,3,5,7,9\)保证没有修改操作。

\(0 \le a[i] \le 10^7\)。

分析

其实这题的 \(Trie\) 树可以不用可持久化

因为前缀会有一些奇奇怪怪的特判,所以我的 \(Trie\) 树里存的是后缀

要满足 \(a[p]\ xor\ a[p+1]\ xor ... xor\ a[N]\ xor\ x\) 最大

不妨设后缀异或和为 \(sum\)

那么就有 $ \sum_{i=p}^N sum[i]\ xor\ x$ 最大

单次操作可以用 \(Trie\) 树 实现

对于多组询问,我们只需要按照每一次询问的右端点从小到大离线排序即可

对于左端点,我们记录一下在 \(Trie\) 树中这个节点最晚在哪一次操作中被加入即可

常数比可持久化 \(Trie\) 树小不少,目前是最优解

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define rg register
inline int read(){
rg int x=0,fh=1;
rg char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*fh;
}
const int maxn=6e5+5,maxk=34;
int a[maxn],sum[maxn],n,m,ans[maxn],cnt,top;
char s[maxn];
struct asd{
int l,r,id,val;
}b[maxn];
bool cmp(asd aa,asd bb){
return aa.r<bb.r;
}
int tr[maxn*10][2],mmax[maxn*10][2];
void ad(rg int val,rg int id){
rg int now=0;
for(rg int i=30;i>=0;i--){
rg int k=(val>>i)&1;
if(!tr[now][k]){
tr[now][k]=++cnt;
mmax[now][k]=id;
} else {
mmax[now][k]=std::max(mmax[now][k],id);
}
now=tr[now][k];
}
}
int cx(rg int val,rg int id){
rg int now=0,nans=0;
for(rg int i=30;i>=0;i--){
rg int k=(val>>i)&1;
if(tr[now][k^1] && mmax[now][k^1]>=id){
now=tr[now][k^1];
nans+=(1<<i);
} else {
now=tr[now][k];
}
}
return nans;
}
int main(){
n=read(),m=read();
for(rg int i=1;i<=n;i++){
a[i]=read();
}
rg int aa,bb,cc;
for(rg int i=1;i<=m;i++){
scanf("%s",s);
if(s[0]=='A'){
aa=read();
a[++n]=aa;
} else {
aa=read(),bb=read(),cc=read();
top++;
b[top].l=aa,b[top].r=bb,b[top].val=n,b[top].id=cc;
}
}
for(rg int i=n;i>=1;i--){
sum[i]=sum[i+1]^a[i];
}
for(rg int i=1;i<=top;i++){
b[i].val=sum[b[i].val+1]^b[i].id;
b[i].id=i;
}
std::sort(b+1,b+1+top,cmp);
rg int head=1;
for(rg int i=1;i<=top;i++){
while(head<=b[i].r){
ad(sum[head],head);
head++;
}
ans[b[i].id]=cx(b[i].val,b[i].l);
}
for(rg int i=1;i<=top;i++){
printf("%d\n",ans[i]);
}
return 0;
}

P4735 最大异或和 01 Trie的更多相关文章

  1. CSU 1216异或最大值 (0-1 trie树)

    Description 给定一些数,求这些数中两个数的异或值最大的那个值 Input 多组数据.第一行为数字个数n,1 <= n <= 10 ^ 5.接下来n行每行一个32位有符号非负整数 ...

  2. hdu 4825 Xor Sum (01 Trie)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825 题面: Xor Sum Time Limit: 2000/1000 MS (Java/Others) ...

  3. [TJOI2018] Xor 异或 (可持久化Trie,树链剖分)

    题目描述 现在有一颗以 1 为根节点的由 n 个节点组成的树,树上每个节点上都有一个权值 \(v_i\).现在有 Q 次操作,操作如下: 1 x y :查询节点 x 的子树中与 y 异或结果的最大值. ...

  4. [一本通学习笔记] 字典树与 0-1 Trie

    字典树中根到每个结点对应原串集合的一个前缀,这个前缀由路径上所有转移边对应的字母构成.我们可以对每个结点维护一些需要的信息,这样即可以去做很多事情. #10049. 「一本通 2.3 例 1」Phon ...

  5. 可持久化0-1 Trie 简介

    Trie树是字符串问题中应用极为广泛的一种数据结构,可以拓展出AC自动机.后缀字典树等实用数据结构. 然而在此我们考虑0-1 Trie的应用,即在序列最大异或问题中的应用. 这里的异或是指按位异或.按 ...

  6. 洛谷 P4735 最大异或和 解题报告

    P4735 最大异或和 题目描述 给定一个非负整数序列\(\{a\}\),初始长度为\(N\). 有\(M\)个操作,有以下两种操作类型: A x:添加操作,表示在序列末尾添加一个数\(x\),序列的 ...

  7. Bzoj3261/洛谷P4735 最大异或和(可持久化Trie)

    题面 Bzoj 洛谷 题解 显然,如果让你查询整个数列的最大异或和,建一颗\(01Trie\),每给定一个\(p\),按照二进制后反方向跳就行了(比如当前二进制位为\(1\),则往\(0\)跳,反之亦 ...

  8. 可持久化+Trie || BZOJ 3261最大异或和 || Luogu P4735 最大异或和

    题面:最大异或和 代码: #include<cstdio> #include<cstring> #include<iostream> using namespace ...

  9. P4735 最大异或和 /【模板】可持久化Trie

    //tire的可持久化 //线段树的可持久化——主席树 //可持久化的前提:本身的拓扑结构在操作时不变 //可以存下来数据结构的所有历史版本 //核心思想:只记录每一个版本与前一个版本不一样的地方 / ...

随机推荐

  1. 【PYTEST】第四章Fixture

    知识点: 利用fixture共享数据 conftest.py共享fixture 使用多个fixture fixture作用范围 usefixture 重命名 1. 利用fixture共享数据 test ...

  2. IntelliJ IDEA 行注释的缩进设置(不自动添加注释到行首)

    目录 现状 修改对比 最后 现状 想注释一行或一个方法,//注释总是生成在行首: 修改对比 要修改的配置在这: 我们可以在注释后添加一个空格,就变成了: 最后 设置完了看下注释效果: 这看起来才舒服.

  3. mongodb分页查询,排序

    mongodb代码 根据时间倒序,查看10条 db.表名.find({"_id":"xxx"}).sort({"inserted":-1}) ...

  4. Codeforces Round #660 (Div. 2) A、B、C题解

    A. Captain Flint and Crew Recruitment #构造 题目链接 题意 定义一类正整数,能够被\(p*q\)表示,其中\(p.q(1<p<q)\)均为素数,称之 ...

  5. L - Deque 题解(区间dp)

    题目链接 题目大意 给你一个双端队列里面有n个数组元素(n<=3000) 有两个人,每次一个人都可以选择队列里的首元素或者尾元素删除,轮流进行,删除后那个人即可获得这个元素的值 第一个人的总权值 ...

  6. EdgeConnect: Structure Guided Image Inpainting using Edge Prediction

    论文 pytorch 引言 语义分割获取边缘信息指导修复其二 存在的问题:之前方法能够生成具有有意义结构的缺失区域,但生成的区域往往模糊或边缘部分存在伪影. 提出问题:提出了一个两阶段的模型,将inp ...

  7. LaTeX文档的基本结构

    正文提纲的构建代码及注释: 显示效果: 目录结构与换行的代码及注释: 显示效果: 具体的有关的信息可以具体查看ctex文档,可以在导言区进行全局的设置,比如标题居中设置等.

  8. redis 五大数据类型使用

    redis 五大数据类型使用 字符串str 单个值 127.0.0.1:6379> set name pp # 设置键值[O(1)] OK 127.0.0.1:6379> setex na ...

  9. day3(django配置跨域)

    1.跨越原理 1. 首先浏览器安全策略限制js ajax跨域访问服务器 2. 如果服务器返回的头部信息中有当前域: // 允许 http://localhost:8080 这个网站打开的页面中的js访 ...

  10. Linux 硬盘挂载及开机挂载

    一.分区 主分区.扩展分区.逻辑分区的区别 主分区:包含操作系统启动所必需的文件和数据的硬盘分区,如需在硬盘上安装操作系统,该硬盘必须得有一个主分区 扩展分区:除主分区外的分区,不能直接使用,必须再划 ...