bzoj3261 最大异或和(可持久化Trie)
来源:互联网 发布:c专家编程pdf 非扫描 编辑:程序博客网 时间:2024/05/15 09:36
bzoj3261 最大异或和
原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3261
题意:
给定一个非负整数序列 {a},初始长度为 N。
有 M个操作,有以下两种操作类型:
1 、A x:添加操作,表示在序列末尾添加一个数 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<=300000 ,0<=a[i]<=10^7
题解:
(重写数组版…)
因为有Add操作,维护后缀的Trie是困难的,于是考虑转化成前缀。
那么:
令pre[i]=a[1]^a[2]^……a[i]
a[p] ^ a[p+1] ^ … ^ a[N] ^ x=pre[p-1]^pre[n]^x
于是变成可持久化Trie维护各个位置的前缀异或和,在其中查询x^pre[n]与这些前缀中的一个能够异或出的最大值。
注意:
原来查询 [L,R]区间,转化后是 [L-1,R-1]的前缀,然后可持久化Trie又要用到root[(L-1)-1],
如果从1开始这就有-1了,于是从2开始,先在root[1]加个0进去。
YYR学长的平方分割大法:
我们先来考虑,若没有添加操作显然可以将所的后缀异或和建成持久化Trie树来做。
那如果添加了 k个元素呢?
查询时可以将 x异或上添加的 k个元素,再到Trie中查询。实际上也就是每添加 lim 个元素后,重新构建数据结构。
假设查询和添加操作次数相近,那么这道题样做的话
建树总复杂度 O(N * 位数 * (N/ lim )) ,
查询总复杂度 O(N * (lim + 位数 )) 。
利用前面的方法,可以得到 lim 取 sqrt (N * (N * 位数 ) 时较优。
复杂度O(N * sqrt sqrt (N * (N * 位数 ))
代码:
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int P=30;const int N=600005;struct node{ int ch[2],size;}tr[N*35];int n,m,tail=0,a[N],root[N];void insert(int pre,int &now,int val,int p){ now=++tail; tr[now]=tr[pre]; tr[now].size++; if(p==-1) return; int opt=(val>>p)&1; insert(tr[pre].ch[opt],tr[now].ch[opt],val,p-1);}int query(int pre,int nd,int val,int p,int ans){ if(p==-1) return ans; int opt=(val>>p)&1; opt=opt^1; int ns=tr[tr[nd].ch[opt]].size; int ps=tr[tr[pre].ch[opt]].size; if(ns-ps>0) return query(tr[pre].ch[opt],tr[nd].ch[opt],val,p-1,ans+(1<<p)); else return query(tr[pre].ch[opt^1],tr[nd].ch[opt^1],val,p-1,ans);}int main(){ scanf("%d%d",&n,&m); n++; for(int i=2;i<=n;i++) scanf("%d",&a[i]); a[0]=a[1]=0; for(int i=2;i<=n;i++) a[i]=a[i-1]^a[i]; root[0]=0; tr[0].ch[0]=tr[0].ch[1]=tr[0].size=0; for(int i=1;i<=n;i++) insert(root[i-1],root[i],a[i],P); while(m--) { char opt[5]; int x,l,r; scanf("%s",opt); if(opt[0]=='A') { n++; scanf("%d",&a[n]); a[n]^=a[n-1]; insert(root[n-1],root[n],a[n],P); } else { scanf("%d%d%d",&l,&r,&x); x=x^a[n]; printf("%d\n",query(root[l-1],root[r],x,P,0)); } } return 0;}
- bzoj3261 最大异或和(可持久化Trie)
- 【BZOJ3261】最大异或和【可持久化Trie树】
- [BZOJ3261][最大异或和][可持久化Trie]
- [可持久化Trie] BZOJ3261: 最大异或和
- bzoj3261 最大异或和【可持久化trie树】
- [BZOJ3261]最大异或和(可持久化trie树)
- 【bzoj3261】【最大异或和】可持久化trie树+贪心
- bzoj3261最大异或和&&可持久化Trie树详解
- bzoj3261 最大异或和(可持久化字典树)
- BZOJ3261最大异或和(可持久化字典树)
- BZOJ3261: 最大异或和(可持续化Trie)
- [BZOJ3261]-可持久化trie
- BZOJ 3261 最大异或和 可持久化Trie
- BZOJ 3261 最大异或和 可持久化Trie
- 3261: 最大异或和 可持久化trie
- [BZOJ]3261: 最大异或和 可持久化Trie
- BZOJ 3261 最大异或和 && qwb VS 去污棒(可持久化01Trie)
- bzoj3261: 最大异或和
- 关于mybatis使用的几个小问题
- 相机标定(Camera calibration)原理、步骤
- tree下subtree.node NotImplementedError: Use label() to access a node label.报错
- 临时表
- 我对小班研讨课的感受
- bzoj3261 最大异或和(可持久化Trie)
- D-数圈圈(数位dp)
- 爬虫防爬措施
- ssh
- org.apache.commons.lang.exception.NestableRuntimeException的解决方法
- 画地为Mask,随心所欲的高效遮罩组件[Unity]
- 收件人
- Anaconda安装Graphviz(win10)
- 吴恩达深度学习第一课第三周课后作业