P4735 最大异或和(可持久化字典树)
题目链接:P4735 最大异或和
Description
给定一个非负整数序列 {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 最大,输出最大是多少。
Input
第一行包含两个整数 N ,M,含义如问题描述所示。
第二行包含 N个非负整数,表示初始的序列 A 。
接下来 M行,每行描述一个操作,格式如题面所述。
Output
假设询问操作有 T个,则输出应该有 T行,每行一个整数表示询问的答案。
题目分析:
记,那么操作2就是求的最大值。
因为这里有个,很显然没有可持久化数据结构是整不了的,
我们在每一个时间戳使用上一个时间戳的信息建一个新的字典树节点链,这个旧的节点如果存在,就复制上一个时间戳的节点,并将cnt[newnode]值设置为上一个节点的cnt+1,如果不存在就设置为1。
这样我们让任意两个时间戳(L-1,R)的cnt做差,如果不为0,就说明在区间[L,R]中存在这个节点。
这样我们就能得到一个任意时间段内的字典树情况,在这个字典树中查找我们要的一个值(与异或起来最大的值)就可行了。
下面代码中将整个序列a在第一个位置设置为0,其他值全部后移一位,这样写起来就可以当作,后面查询操作写起来会方便一些。
代码:
#include<stdio.h>
#include<cstdio>
#include<algorithm>
using namespace std;const int MAXN = 600005;
int cnt[MAXN*26], ch[MAXN*26][2], root[MAXN], tot;
int n, m, sum[MAXN];
//传入根节点ne插入x返回新树根节点
int insert(int ne, int x){int nd, tmp; nd = tmp = ++tot;for(int i = 23;i>=0;i--){ch[nd][0] = ch[ne][0], ch[nd][1] = ch[ne][1];cnt[nd] = cnt[ne] + 1;int id = ((x>>i)&1);nd = ch[nd][id] = ++tot, ne = ch[ne][id];}cnt[nd] = cnt[ne] + 1;return tmp;
}
//查询 r-l 树中的x
int query(int l,int r,int x){int tmp = 0;for(int i = 23;i>=0;i--){int id = ((x>>i)&1);if(cnt[ch[r][id^1]] - cnt[ch[l][id^1]]){tmp |= (1<<i);r = ch[r][id^1], l = ch[l][id^1];}else{r = ch[r][id], l = ch[l][id];}}return tmp;
}
int main()
{scanf("%d%d",&n,&m); n++;root[1] = insert(0,0);for(int i = 2;i<=n;i++){scanf("%d",&sum[i]); sum[i] ^= sum[i-1];root[i] = insert(root[i-1], sum[i]);}while(m--){char s[5];scanf("%s", s);if(s[0] == 'Q'){int l,r,x;scanf("%d%d%d",&l,&r,&x);printf("%d\n",query(root[l-1],root[r],x^sum[n]));}else{n++;scanf("%d",&sum[n]); sum[n] ^= sum[n-1];root[n] = insert(root[n-1], sum[n]);}}return 0;
}
P4735 最大异或和(可持久化字典树)相关推荐
- P4735 最大异或和 可持久化trie树
可持久化01trie类似主席树思想 但是不支持版本差(也可以加一个siz 做差) 只能再维护一个左端点的最大值即可 #include<bits/stdc++.h> using ...
- [十二省联考 2019] 异或粽子(可持久化字典树 + 二叉堆)
problem luogu-P5283 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 nnn 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 111 到 nn ...
- Luogu P4735(可持久化字典树)
链接:点击打开链接 题意: 给定一个非负整数序列 {a},初始长度为n. 有 m 个操作,有以下两种操作类型: A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 n+1. Q l r x:询 ...
- 中石油训练赛 - 腿部挂件(可持久化字典树)
题目描述 Jim是一个热爱打游戏的小伙子,可惜他的游戏水平不太行,以至于经常在游戏里被别人欺负.而且Jim不仅游戏玩的菜,他还很爱喷人,但是由于自己的垃圾操作,他又喷不过别人.为了改善这种局面,Jim ...
- 【bzoj3261】最大异或和 可持久化Trie树
题目描述 给定一个非负整数序列 {a},初始长度为 N. 有M个操作,有以下两种操作类型: 1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1. 2.Q l r x: ...
- 可持久化-可持久化字典树
可持久化-Trie可持久化 2021年8月2日 可持久化干什么? 可持久化,就是记录每次更改的版本,以便于后续使用从前的版本.对于字典树,就是对每次加入的字符串按次进行记录. 算法原理 建树时,每次新 ...
- BZOJ3261: 最大异或和(可持久化trie树)
题意 题目链接 Sol 设\(sum[i]\)表示\(1 - i\)的异或和 首先把每个询问的\(x \oplus sum[n]\)就变成了询问前缀最大值 可持久化Trie树维护前缀xor,建树的时候 ...
- BZOJ 3261 最大异或和 可持久化Trie树
题目大意:给定一个序列,提供下列操作: 1.在数组结尾插入一个数 2.给定l,r,x,求一个l<=p<=r,使x^a[p]^a[p+1]^...^a[n]最大 首先我们能够维护前缀和 然后 ...
- P4735 最大异或和(可持久化字典树 ? 主席树)
异或满足可减性,所以可以维护前缀和,然后 a[p] xor a[p + 1] xor ... xor a[n] xor = s[p - 1] xor s[n] xor然后就只要维护s[].添加很好维护 ...
最新文章
- 事半功倍系列 javascript
- linux下kafka常用命令
- 【Linux系统编程】特殊进程之僵尸进程
- 快速搭建实验环境:使用 Terraform 部署 Proxmox 虚拟机
- 最近总结——关于自己的基础问题
- 大规模中文自然语言处理语料(百科,问答、新闻,翻译)
- springboot13 页面国际化(i18n)
- [原创]Java开发如何在线打开Word文件
- wps画流程图交叉弧形_wps画的流程图打印不清晰|wps怎么绘制出立体流程图?wps绘制出立体流程图的方法...
- java“的注脚_百度得到的数据如何写脚注
- spring cloud tencent:框架概括及组件详解(一)
- 显示器分辨率的英文(XGA、SXGA、UXGA、WSXGA等等来表示)
- TPC好像是这么回事儿
- android手机安装carplay,安卓系统适用carplay经验分享
- c语言 substr,如何在C语言实现substr()
- linux——搭建NTP服务器
- pgsql之create user与create role的区别
- 优秀开源项目之三:高性能、高并发、高扩展性和可读性的网络服务器架构State Threads...
- Oracle的表简单介绍
- pytorch从hdfs载入模型、从二进制字符串载入模型
热门文章
- 文字语义纠错技术探索与实践-张健
- 螺纹检测案例-螺距测量-大径小径检测-螺牙检测
- 图片放大出现锯齿问题
- 鱼眼摄像头 实时动、静目标的检测,跟踪,分类
- 逐字稿整理-中/TED演讲:如何训练思维,突破局限?(大花猫冯夏)
- 根据ip或者自动识别当前用户所在国家、地区、城市
- DELL OMSA(SrvAdmin)-监控软件与Promethues结合
- 一本好的“错题集”如何做?看这里
- “对不起,您只能拨打中国移动的号码…”
- p坚持csma协议 仿真‘_成都市与上海交通大学签署系列合作协议