本题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3261

题目描述

给定一个非负整数序列{a},初始长度为N。
有M个操作,有以下两种操作类型:
1、Ax:添加操作,表示在序列末尾添加一个数x,序列的长度N+1。
2、Q l r x:询问操作,你需要找到一个位置p,满足l<=p<=r,使得:
a[p] xor a[p+1] xor ... xor a[N] xor x 最大,输出最大是多少。

输入

第一行包含两个整数 N  ,M,含义如问题描述所示。   
第二行包含 N个非负整数,表示初始的序列 A 。 
接下来 M行,每行描述一个操作,格式如题面所述。

输出

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

样例输入

5 5
2 6 4 3 6
A 1
Q 3 5 4
A 4
Q 5 7 0
Q 3 6 6
对于测试点 1-2,N,M<=5 。
对于测试点 3-7,N,M<=80000 。
对于测试点 8-10,N,M<=300000 。
其中测试点 1, 3, 5, 7, 9保证没有修改操作。
0<=a[i]<=10^7。

样例输出

4
5
6
 

题解:

在这道题目之前,我想读者需要一个前置知识便于理解。请看我的另一篇博客:https://www.cnblogs.com/xxzh/p/9178838.html
如果学会了这个知识的话,也就是知道了如何使用一颗01 Trie树
那么考虑这道题,很显然,现在我们需要维护一颗可持久化trie树。如果不清楚静态主席树原理的,请移步我的另一篇博客:https://www.cnblogs.com/xxzh/p/9158819.html
 
正式开始对这题讲解:
对于每次操作Q,它给的算式太鬼了,实际上应该化成max( (a[n] xor x)xor a[p-1] ) p∈[l,r];
 
对每个前置建立Trie,建立原理参考主席树博客。
在建树的过程中,很重要的一点就是我们每次插入的节点其实是原来a数组中的前缀。也就是说我们维护的是前缀和的前缀(有点绕读者仔细琢磨)
 
然后注意看算式,我们每次找的其实是p-1,注意是p-1而不是p。
也就是本来我们query查找的应该是l-1到r,由于是p-1我们现在查找的是l-2到r-1
当然,对于处理p-1我们也有方法,只需要在原来的数组a之前加一个0,这样的话就可以直接算l-1到r了
 
具体的操作还是贪心的从高位到低位建立Trie,查询的时候注意减一下
下面附上代码:
#include<bits/stdc++.h>
using namespace std; const int maxn=6e5+;
int n,m,sz;
int t[maxn<<][],sum[maxn<<],b[maxn],q[maxn];
inline int read(){
char ch=getchar();
int s=,f=;
while (!(ch>=''&&ch<='')) {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
int ins(int last,int val)
{
int res,k;
res=k=++sz;
for (int i=;i>=;i--)
{
sum[k]=sum[last]+;
t[k][]=t[last][];t[k][]=t[last][];
bool d=val&(<<i);
k=t[k][d]=++sz;last=t[last][d];
}
sum[k]=sum[last]+;
return res;
}
int query(int k1,int k2,int val)
{
int res=;
for (int i=;i>=;i--)
{
bool d=val&(<<i);
if (sum[t[k2][d^]]-sum[t[k1][d^]]>){
res|=(<<i);
k1=t[k1][d^];
k2=t[k2][d^];
}
else k1=t[k1][d],k2=t[k2][d];
}
return res;
}
int main()
{
n=read()+;m=read();
q[]=ins(q[],b[]);
for (int i=;i<=n;i++)
{
b[i]=b[i-]^read();//注意插入trie的是前缀和
q[i]=ins(q[i-],b[i]);
}
for (int i=;i<=m;i++)
{
char ch=getchar();
while (!(ch=='A'||ch=='Q')) ch=getchar();
if (ch=='A') {
++n;
b[n]=b[n-]^read();
q[n]=ins(q[n-],b[n]);
}
else {
int l=read(),r=read(),x=read();
printf("%d\n",query(q[l-],q[r],x^b[n]));
}
}
return ;
}

BZOJ3261 最大异或和 解题报告(可持久化Trie树)的更多相关文章

  1. [十二省联考2019] 异或粽子 解题报告 (可持久化Trie+堆)

    interlinkage: https://www.luogu.org/problemnew/show/P5283 description: solution: 显然有$O(n^2)$的做法,前缀和优 ...

  2. HDU4825:Xor Sum 解题报告(0/1 Trie树)

    Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数. 随后 Prometheus 将向 Ze ...

  3. 【洛谷5283】[十二省联考2019] 异或粽子(可持久化Trie树+堆)

    点此看题面 大致题意: 求前\(k\)大的区间异或和之和. 可持久化\(Trie\)树 之前做过一些可持久化\(Trie\)树题,结果说到底还是主席树. 终于,碰到一道真·可持久化\(Trie\)树的 ...

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

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

  5. 【bzoj3261】【最大异或和】可持久化trie树+贪心

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61705397 Description 给定一个非 ...

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

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

  7. [BZOJ3261&BZOJ3166]可持久化trie树及其应用

    可持久化trie树 可持久化trie树现在想来是比较好理解的了,但却看了一个下午... 相当于对于每个状态建立一条链(或者说一棵trie),求解的时候只要让两个点按照相同的步子走然后看sum的大小关系 ...

  8. [十二省联考2019]异或粽子——可持久化trie树+堆

    题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...

  9. bzoj 3261: 最大异或和 (可持久化trie树)

    3261: 最大异或和 Time Limit: 10 Sec  Memory Limit: 512 MB Description       给定一个非负整数序列 {a},初始长度为 N.       ...

随机推荐

  1. 取消记录tableView选中效果

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self. ...

  2. nginx源代码分析--从源代码看nginx框架总结

    nginx源代码总结: 1)代码中没有特别绕特别别扭的编码实现.从变量的定义调用函数的实现封装,都非常恰当.比方从函数命名或者变量命名就能够看出来定义的大体意义,函数的基本功能,再好的架构实如今编码习 ...

  3. JAVA网络编程--UDP通信

    首先网络传输数据需了解例如以下三点 1.找到对方IP 2.数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序用数字进行了标识.为了方便称呼这个数字,叫做port,逻辑por ...

  4. C++ Primer Plus的若干收获--(三)

    有时候怀疑真是怀疑自己走的路究竟是不是正确的.作为一个土生土长数学系学生,却对数学毫无兴趣,没事的时候就喜欢躲在图书馆看看有关计算机的书.有时候期末考试时候会挂个一两门的数学专业课,有时候真希望数学课 ...

  5. Codeforces 703D Mishka and Interesting sum 离线+树状数组

    链接 Codeforces 703D Mishka and Interesting sum 题意 求区间内数字出现次数为偶数的数的异或和 思路 区间内直接异或的话得到的是出现次数为奇数的异或和,要得到 ...

  6. python 3.x 学习笔记10 (析构函数and继承)

    1.类变量的用途:大家公用的属性,节省开销(内存) 2.析构函数 在实例释放和销毁的时候执行的,通常用于做一些收尾工作,如关闭一些数据库链接和打开的临时文件 3.私有方法两个下划线开头,声明该方法为私 ...

  7. dev c++与VC assist的杂记

    最近要处理一些数据,于是把旧本拿出来用用.但是发现旧本运行速度很慢. 分析之后发现是瑞星的老版本程序里面加了游戏的云存储节点的注册表键.果断把该键删了之后,CPU使用率从66%以上降到24%左右. 然 ...

  8. 当一个元素被浮动后,它的display是否会被默认指定为block?

    css 浮动后的元素不论是什么display的都默认是block就是设置inline也是block IE/6出现双边框的原因 出现双边距的条件是当浮动元素的浮动方向和margin的方向一致时才会出现. ...

  9. Android 设置AlertDialog的大小 .

    AlertDialog dialog = builder.setTitle("消息列表") .setView(layout) .create(); dialog.show(); / ...

  10. Android Fragment中调用getActivity为null的问题

       在使用fragment的时候经常会遇到getActivity()为null的情况.比如我在一个异步网路请求的回调中调用了getActivity()就会出现空指针问题.之前解决这个问题,通常都是直 ...