可持久化01Trie

例题:

解释:

首先这里要求连续异或,所以存储前缀异或和数组。首先的话,我们只考虑前r个版本的Trie,所以以root[r]为根节点的Trie就是1到r位置数。但是,还有一个l左端点,所以我们对于每一个节点来说,额外存储一下max_id,表示的就是以当前节点为子树的最大的i。那这个有什么用呢?

这里我们都是动态开点,也就是假设当前我们的数是1,所以我们要向下遍历找到一个0,由于我们是有限制条件的,所以对于每一个节点,加入他的0的这个儿子的max_id大于我们的限制条件,也就是这个子树里面存在一个s{i],它的下标大于或等于我们的限制条件,所以我们就可以往0这个方向走。

动态开点思路:对于每一个s[i]我们都去开这个数的01串,也就是一个链子,刚开始是我们的根节点,也就是我们的版本(第几版)。假设当前数是(二进制:101010),我们先开了一个根节点(第几版),于是我们继续开一个1这个节点,如果它的上一个版本中的根节点有0这个儿子,那么我们就让上一个版本的0这个儿子指向当前的根节点(也就是直接拷贝)。然后继续开点,开0这个节点,只要遇到不同的,就直接拷贝,如果上一个版本存在当前的链子的前半部分,我们也是必须开的,只有不同的我们才会去复制。

那么这样执行下来,就会存下每一个版本的Trie,也就是我们的可持久化Trie,那么这到底有什么用呢?下面就用上面这个例题来介绍它的用处!

由于当前是由区间限制的,不像一组数据中找两个数他们的异或值最大,没有区间限制的话,用我们的Trie就可以了。首先如果我们只考虑1到r这个条件的话,那么直接从第r个版本的Trie开始找一个数就可以了。然后在考虑数必须大于等于l这个条件,由于我们存储了max_id,也就是下一个节点的max_id,只要大于等于限制条件,就可以遍历这个节点。假设max_id是3,限制条件是2,表示的是这个字数有一个数它的下标是3,所以就可以遍历这个节点,反之,就不可以遍历,因为每一个节点它的下标大于限制条件,都是l前面的数,所以就不能遍历。

所以,直接上代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 600010,M = N*25;
int n, m;
int tr[M][2], idx;
int root[N];
int s[N];
int max_id[M];

void insert(int i, int k, int p, int q)
{
	if (k < 0)
	{
		max_id[q] = i;
		return ;
	}
	int u = s[i] >> k & 1;
	if (p)tr[q][u^1] = tr[p][u^1];
	tr[q][u] = ++idx;
	insert(i, k - 1, tr[p][u], tr[q][u]);
	max_id[q] = max(max_id[tr[q][0]],max_id[tr[q][1]]);
}

int query(int root, int limit, int c)
{
	int p = root;
	for (int i = 23; i >= 0; i--)
	{
		int u = c >> i & 1;
		if (max_id[tr[p][!u]] >= limit && tr[p][!u])p = tr[p][!u];
		else p = tr[p][u];
	}
	return c ^ s[max_id[p]];
}

int main()
{
	cin >> n >> m;

	root[0] = ++idx;
	insert(0,23,0,root[0]);

	for (int i = 1; i <= n; i++)
	{
		int x;
		scanf("%d", &x);
		root[i] = ++idx;
		s[i] = s[i - 1] ^ x;
		insert(i, 23, root[i - 1], root[i]);
	}

	char op[2]; int l, r, x;
	while (m--)
	{
		scanf("%s", op);
		if (*op == 'A')
		{
			scanf("%d", &x);
			n++;
			root[n] = ++idx;
			s[n] = s[n - 1] ^ x;
			insert(n, 23, root[n - 1], root[n]);
		}
		else
		{
			scanf("%d%d%d", &l, &r, &x);
			printf("%d\n", query(root[r - 1], l - 1, s[n] ^ x));
		}
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/123546.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

竞赛选题 深度学习机器视觉车道线识别与检测 -自动驾驶

文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分…

OpenCV 输出文本

PutText() 输出文本 OpenCV5 将支持中文字符的输出, 当前版本OpenCV4原生不支持, 可以使用Contrib包FreeType方式实现, 不过比较麻烦.为了省事, 也可以通过将Mat转成bitmap,然后使用GDI方式输出中文字符. 示例代码 /// <summary>/// OpenCV暂时不能支持中文字符输出,显示…

Python爬虫入门教程之快速理解HTTP协议

文章目录 前言一、HTTP协议是什么&#xff1f;二、HTTP 请求三、请求行四、请求首部五、请求体六、HTTP 响应七、响应行八、响应首部九、响应体总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①…

计算机基础知识49

三板斧的使用(views.py) 三个方法&#xff1a;HttpResponse: 返回的是字符串render : 返回html文件redirect : 返回加载HTML页面的 def html(request):print(from html)# return HttpResponse(request) # 它返回的是字符串return render(request,html.html) # 返回html# ret…

跟着森老师学React Hooks(1)——使用Vite构建React项目

Vite是一款构建工具&#xff0c;对ts有很好的支持&#xff0c;最近也是在前端越来越流行。 以往的React项目的初始化方式大多是通过脚手架create-react-app(本质是webpack)&#xff0c;其实比起Vite来构建&#xff0c;启动会慢一些。 所以这次跟着B站的一个教程&#xff0c;使用…

对称二叉树(C++解法)

题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false C代码 #include <iostrea…

Blender做一个小凳子学习笔记

文章目录 创建椅座椅子腿靠背渲染 本文是这个B站视频的学习笔记&#xff1a;【Blender】爆肝两个月&#xff01;拜托三连了&#xff01;这绝对是全B站最用心的&#xff08;没有之一&#xff09;Blender 3D建模零基础入门 创建椅座 首先&#xff0c;需要了解其左上角和右上角的…

【教3妹学编程-算法题】 在树上执行操作以后得到的最大分数

3妹&#xff1a;2哥&#xff0c;今日都立冬了&#xff0c; 可是天气一点都不冷。 2哥 : 立冬了&#xff0c;晚上要不要一起出去吃饺子&#xff1f;&#x1f95f; 3妹&#xff1a;好呀好呀&#xff0c;2哥请吃饺子喽 2哥 : 歪歪&#xff0c;我说的是一起出去吃&#xff0c;没说我…

【Linux】了解文件的inode元信息,以及日志分析

目录 一、inode表结构&#xff0c;以及元信息 1、了解inode信息有哪些 2、关于inode表的说明 Linux中访问文件的过程&#xff1a; 3、硬连接与软连接的区别&#xff0c;&#xff08;请看前面&#xff0c;写过的&#xff09; 二、文件系统的备份与恢复 三、几种常见的日志…

node插件MongoDB(三)—— 库mongoose 的使用

前言 提示&#xff1a;使用mongoose 的前提是你安装了node和 MongoDB。 mongoose 官网文档&#xff1a;http://mongoosejs.net/docs/index.html 文章目录 前言一、安装二、基本使用1. 打开bin目录的mongod.exe文件2. 基本使用的代码&#xff08;连接mongodb 服务&#xff09;3.…

理解MySQL的日志 Redo、Undo

理解MySQL的Redo日志和Undo日志 1、MySQL 日志文件解决的问题2、redo 日志2.1、redo log 的组成2.2、redo log 刷盘策略2.3、MySQL 的 redo log解决了哪些问题 3、undo 日志3.1、undo 日志作用3.2、undo log 的类型3.3、undo log 的生命周期3.4、事务回滚相关的几个隐藏字段 1、…

JAVA安全之Log4j-Jndi注入原理以及利用方式

什么是JNDI&#xff1f; JDNI&#xff08;Java Naming and Directory Interface&#xff09;是Java命名和目录接口&#xff0c;它提供了统一的访问命名和目录服务的API。 JDNI主要通过JNDI SPI&#xff08;Service Provider Interface&#xff09;规范来实现&#xff0c;该规…

率能SS6216-单通道直流有刷电机驱动芯片

产品描述&#xff1a; SS6216是一款单通道直流有刷驱动芯片&#xff1b;工作电压为 2.0V&#xff5e;7.2V&#xff0c;每个通道的负载电流可达1.4A;峰值输出电流1.6A&#xff1b;低待机电流 (typ. 0.1uA&#xff09;低导通电阻0.6ohm(采用SOP8/SOT23-6两种封装)满足产品小型化…

字符编码转换时发生内存越界引发的摄像头切换失败问题的排查

目录 1、问题说明 2、初步分析 3、字符串字符编码说明 4、进一步分析 5、为啥在日常测试时没有遇到切换摄像头失败的问题呢&#xff1f; 6、华为MateBook笔记本使用高通的CPU 7、最后 VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更…

推荐大学生考研党都来使用的白板笔记软件!上岸卷王必备!

考研这条路&#xff0c;对于很多大学生来说&#xff0c;是一条漫漫长路。相信很多人都有这样的体会&#xff1a;看了大量的书籍&#xff0c;记了大量的笔记&#xff0c;但是到了临近考试的时候&#xff0c;却发现复习的内容和思路都不是很清晰&#xff0c;效率不高。 针对这个…

Nginx实现tcp代理并支持TLS加密实验

Nginx源码编译 关于nginx的搭建配置具体参考笔者之前的一篇文章&#xff1a;实时流媒体服务器搭建试验&#xff08;nginxrtmp&#xff09;_如何在线测试流媒体rtmp搭建成功了吗-CSDN博客中的前半部分&#xff1b;唯一变化的是编译参数&#xff08;添加stream模块并添加其对应ss…

骨传导蓝牙耳机推荐,2023骨传导耳机选购攻略

相信大家佩戴入耳式耳机时间长后&#xff0c;都会出现耳朵痛的情况&#xff0c;这也是这类耳机的一个通病了&#xff0c;为了缓解这一问题&#xff0c;骨传导耳机出现了&#xff0c;并且凭借佩戴舒适&#xff0c;并且不会耳痛等优点迅速成为当下最受欢迎的耳机款式&#xff0c;…

Android 内存泄漏分析思路和案例剖析

分析思路 内存泄漏是指 Android 进程中&#xff0c;某些对象已经不再使用&#xff0c;但被一些生命周期更长的对象引用&#xff0c;导致其占用的内存资源无法被GC回收&#xff0c;内存占用不断增加的一种现象&#xff1b;内存泄漏是导致我们应用性能下降、卡顿的一种常见因素&…

鸿蒙开发工具的汉化

1、下载汉化包 汉化插件下载地址&#xff1a;Chinese (Simplified) Language Pack / 中文语言包 - IntelliJ IDEs Plugin | Marketplace 百度网盘下载地址&#xff1a;链接&#xff1a;百度网盘 请输入提取码 DevEco Studio是基于IDEA223版本&#xff0c;下载汉化包时请注意…

Hadoop原理,HDFS架构,MapReduce原理

Hadoop原理&#xff0c;HDFS架构&#xff0c;MapReduce原理 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c…