[BZOJ3261] 最大异或和 (异或前缀和,可持久化Trie)
Description
给定一个非负整数序列{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 最大,输出最大是多少。
Input
第一行包含两个整数 N ,M,含义如问题描述所示。
第二行包含 N个非负整数,表示初始的序列 A 。
接下来 M行,每行描述一个操作,格式如题面所述。
Output
假设询问操作有 T个,则输出应该有 T行,每行一个整数表示询问的答案。
Sample Input
5 5
2 6 4 3 6
A 1
Q 3 5 4
A 4
Q 5 7 0
Q 3 6 6
Sample Output
4
5
6
Hints
对于测试点 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。
Solution
又是一道可持久化 Trie 的套路题,不过一开始被建树难住了...
分析题目:
- 异或有基本性质即 : \({({x}\bigoplus{y})}\bigoplus{y}=x\) .
- 此题要求我们求 \({({a_{p}}\bigoplus{a_{i}})}\bigoplus{a_{n}}\)的值,即\({sum_{p-1}}\bigoplus{sum_{n}}\),其中\(sum\)代表从根节点出发的异或前缀和.
那么我们思路也就很明了了。
我们在Trie中插入每一个前缀和,然后在查询的时候直接查询\((l-2,r-1)\)即可。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=300008;
int T[maxn*2],ch[2*maxn*32][2];
int num[2*maxn*32],n,m;
ll a[maxn*2],tot;int insert(int pre,ll x,int v)
{int rt=++tot;ll c=((x>>v)&1); ch[rt][0]=ch[pre][0];ch[rt][1]=ch[pre][1];num[rt]=num[pre]+1;if(v>=0)ch[rt][c]=insert(ch[pre][c],x,v-1);return rt;
}
ll ans;
void query(int l,int r,ll x,int v)
{ll c=((x>>v)&1);if(num[ch[r][c^1]]-num[ch[l][c^1]]>0){ans+=(1<<v);if(v>=0)query(ch[l][c^1],ch[r][c^1],x,v-1);}elseif(v>=0)query(ch[l][c],ch[r][c],x,v-1);}ll sum[maxn*2];
int main()
{cin>>n>>m;for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int i=1;i<=n;i++)sum[i]=sum[i-1]^a[i];for(int i=1;i<=n;i++)T[i]=insert(T[i-1],sum[i],30);for(int i=1;i<=m;i++){ll x,y,z;char ch[10]; scanf("%s ",ch);if(ch[0]=='A'){scanf("%lld",&x);n++;sum[n]=sum[n-1]^x;T[n]=insert(T[n-1],sum[n],30);}else{ scanf("%lld%lld%lld",&x,&y,&z);z=z^sum[n];ans=0;if(y==1){cout<<z<<endl;continue;}query(T[x-2],T[y-1],z,30);cout<<ans<<endl;}}
}
转载于:https://www.cnblogs.com/Kv-Stalin/p/9326061.html
[BZOJ3261] 最大异或和 (异或前缀和,可持久化Trie)相关推荐
- BZOJ3261: 最大异或和(可持久化trie树)
题意 题目链接 Sol 设\(sum[i]\)表示\(1 - i\)的异或和 首先把每个询问的\(x \oplus sum[n]\)就变成了询问前缀最大值 可持久化Trie树维护前缀xor,建树的时候 ...
- 【bzoj3261】最大异或和 可持久化Trie树
题目描述 给定一个非负整数序列 {a},初始长度为 N. 有M个操作,有以下两种操作类型: 1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1. 2.Q l r x: ...
- Bzoj3261/洛谷P4735 最大异或和(可持久化Trie)
题面 Bzoj 洛谷 题解 显然,如果让你查询整个数列的最大异或和,建一颗\(01Trie\),每给定一个\(p\),按照二进制后反方向跳就行了(比如当前二进制位为\(1\),则往\(0\)跳,反之亦 ...
- BZOJ3261 最大异或和 解题报告(可持久化Trie树)
本题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3261 题目描述 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类 ...
- 可持久化Trie+堆优化 OR Trie树上求XOR第K大 ---- P5283 [十二省联考2019]异或粽子
题目大意 题目大意: 考虑先做个 prefix xor 前缀异或bi=⨁j=1iaj(1≤i≤n)b_i=\bigoplus_{j=1}^{i}a_j(1\leq i \leq n)bi=j=1⨁i ...
- P4735 最大异或和(可持久化trie树、求最大区间异或和)
P4735 最大异或和 我们维护一个前缀异或和:s[i]=a[1]xora[2]xor-a[i−1]xora[i]s[i] = a[1] \ xor\ a[2]\ xor\ - a[i-1] \ xo ...
- Nikitosh 和异或 —— 一道 trie 树的题用可持久化 trie 水 然后翻车了...
题意简介 题目就是叫你找两个不重合的非空区间,使得这两个区间里的数异或后相加的和最大 (看到异或,没错就决定是你了可持久化trie!) 思路 水一波字典树,莫名觉得这题可持久化能过,于是水了一发挂了, ...
- bzoj 3261 最大异或和【可持久化trie】
因为在后面加数字又求后缀和太麻烦,所以xor[p...n]=xor[1...n]^xor[p-1...n]. 首先处理出来区间异或前缀和,对前缀和建trie树(在最前面放一棵0表示最开始的前缀和 然后 ...
- BZOJ 3261: 最大异或和 [可持久化Trie]
3261: 最大异或和 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 1513 Solved: 657 [Submit][Status][Disc ...
最新文章
- c语言 内存搜索,怎么在一段内存中搜索一个十六进制串
- 新的一年babel了解一下
- 计算机系统基础:文件的存取和存储空间管理知识笔记
- Flink 1.10 细粒度资源管理解析
- 信息学奥赛一本通(1404:我家的门牌号)
- .net byte转java byte_CVE20200688的武器化与.net反序列化漏洞那些事
- 动态球html,用html5标签让小球动起来
- SUSE Enterprise Server 12 SP3 64 设置防火墙开放8080端口
- 检查容器内的磁盘占用shell(check_container_disk.sh)
- win10定时关机程序
- 硬件描述语言实验二:一位全加器实验
- 麦克风阵列的同步性、一致性、峰值幅度、RMS、DC偏移
- 《The Django Book 2.0》中文版笔记
- 网上图书订阅系统的WBS图,和WBS字典
- have datatype/md5sum 相关的错误 IndentationError: unexpected indent
- activereport subreport
- List 接口和常用方法
- 电子招投标采购系统之电子招标投标的全流程!企业电子招投标系统源码
- 电脑开机遇到二维码怎么办?
- vue下的@change事件
热门文章
- Struts编程心得
- 机器学习中Python常用库总结(numpy,scipy,matplotlib,pandas)
- html表单和输入方法,HTML 表单和输入
- centos安装python3小白_Centos7 安装Python3
- web---基础知识(更新中)
- JDK注解(内置和自定义)
- 022_Table表格
- 004_Vue按键修饰符
- 001_Ajax简介
- 美版iphone更新系统无服务器,大量美版iPhone“伪装”成国行出现在各大平台,遇到一定不要买...