洛谷 P3834 可持久化线段树 2 题解

【模板】可持久化线段树 2

题目描述

如题,给定 n n n 个整数构成的序列 a a a,将对于指定的闭区间 [ l , r ] [l, r] [l,r] 查询其区间内的第 k k k 小值。

输入格式

第一行包含两个整数,分别表示序列的长度 n n n 和查询的个数 m m m
第二行包含 n n n 个整数,第 i i i 个整数表示序列的第 i i i 个元素 a i a_i ai
接下来 m m m 行每行包含三个整数 l, r, k, 表示查询区间 [ l , r ] [l, r] [l,r] 内的第 k k k 小值。

输出格式

对于每次询问,输出一行一个整数表示答案。

样例 #1

样例输入 #1

5 5
25957 6405 15770 26287 26465 
2 2 1
3 4 1
4 5 1
1 2 2
4 4 1

样例输出 #1

6405
15770
26287
25957
26287

提示

样例 1 解释

n = 5 n=5 n=5,数列长度为 5 5 5,数列从第一项开始依次为 { 25957 , 6405 , 15770 , 26287 , 26465 } \{25957, 6405, 15770, 26287, 26465\} {25957,6405,15770,26287,26465}

  • 第一次查询为 [ 2 , 2 ] [2, 2] [2,2] 区间内的第一小值,即为 6405 6405 6405
  • 第二次查询为 [ 3 , 4 ] [3, 4] [3,4] 区间内的第一小值,即为 15770 15770 15770
  • 第三次查询为 [ 4 , 5 ] [4, 5] [4,5] 区间内的第一小值,即为 26287 26287 26287
  • 第四次查询为 [ 1 , 2 ] [1, 2] [1,2] 区间内的第二小值,即为 25957 25957 25957
  • 第五次查询为 [ 4 , 4 ] [4, 4] [4,4] 区间内的第一小值,即为 26287 26287 26287

数据规模与约定

  • 对于 20 % 20\% 20% 的数据,满足 1 ≤ n , m ≤ 10 1 \leq n,m \leq 10 1n,m10
  • 对于 50 % 50\% 50% 的数据,满足 1 ≤ n , m ≤ 1 0 3 1 \leq n,m \leq 10^3 1n,m103
  • 对于 80 % 80\% 80% 的数据,满足 1 ≤ n , m ≤ 1 0 5 1 \leq n,m \leq 10^5 1n,m105
  • 对于 100 % 100\% 100% 的数据,满足 1 ≤ n , m ≤ 2 × 1 0 5 1 \leq n,m \leq 2\times 10^5 1n,m2×105 ∣ a i ∣ ≤ 1 0 9 |a_i| \leq 10^9 ai109 1 ≤ l ≤ r ≤ n 1 \leq l \leq r \leq n 1lrn 1 ≤ k ≤ r − l + 1 1 \leq k \leq r - l + 1 1krl+1

原题

洛谷P3834——传送门

代码

#include <bits/stdc++.h>
using namespace std;
#define max_Heap(x) priority_queue<x, vector<x>, less<x>>
#define min_Heap(x) priority_queue<x, vector<x>, greater<x>>
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
const double PI = acos(-1);const int maxn = 2e5; // 数据范围
// tot为树中元素下标,从1号根节点开始
int tot, n, m;
// sum[]表示该节点对应区间的数值个数,rt[]记录历史线段树的根节点,ls记录左儿子,rs记录右二子
int sum[(maxn << 5) + 10], rt[maxn + 10], ls[(maxn << 5) + 10], rs[(maxn << 5) + 10]; // 左移运算符是为了给记录历史线段树的过程开辟足够多的节点,需根据具体maxn的值修改(一般不必修改)
// a[]为读入数组,ind[]为离散化后对应元素,len为离散化后元素个数
int a[maxn + 10], ind[maxn + 10], len;int getid(const int &val) // 离散化
{ return lower_bound(ind + 1, ind + len + 1, val) - ind;
}int build(int l, int r) // 建树
{int root = ++tot;if (l == r)return root;int mid = l + r >> 1;ls[root] = build(l, mid);rs[root] = build(mid + 1, r);return root; // 返回该子树的根节点
}int update(int k, int l, int r, int root) // 插入元素
{int dir = ++tot; // 当前节点下标ls[dir] = ls[root], rs[dir] = rs[root], sum[dir] = sum[root] + 1;if (l == r)return dir;int mid = l + r >> 1;if (k <= mid)ls[dir] = update(k, l, mid, ls[dir]);elsers[dir] = update(k, mid + 1, r, rs[dir]);return dir;
}int query(int u, int v, int l, int r, int k) // 查询操作
{int mid = l + r >> 1,x = sum[ls[v]] - sum[ls[u]]; // 通过区间减法得到左儿子中所存储的数值个数if (l == r)return l;if (k <= x) // 若 k 小于等于 x ,则说明第 k 小的数字存储在在左儿子中return query(ls[u], ls[v], l, mid, k);else // 否则说明在右儿子中return query(rs[u], rs[v], mid + 1, r, k - x);
}void init() // 初始化主席树
{cin >> n >> m;for (int i = 1; i <= n; ++i)cin >> a[i];memcpy(ind, a, sizeof(ind));// 离散化sort(ind + 1, ind + n + 1);                   // 排序len = unique(ind + 1, ind + n + 1) - ind - 1; // 去重,并记录不同元素的个数rt[0] = build(1, len);                        // 建第一个线段树(尚未插入元素)for (int i = 1; i <= n; ++i)rt[i] = update(getid(a[i]), 1, len, rt[i - 1]); // 更新后续一个一个插入元素后的线段树
}int l, r, k;void work() // 回答询问
{while (m--){cin >> l >> r >> k;// 返回区间[l,r]中第k小值cout << ind[query(rt[l - 1], rt[r], 1, len, k)] << '\n';}
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);init();work();return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【磁盘清理】/var/lib/docker/overlay2 占用空间过大

找到对应的容器 1.查看目前的容器占用的空间(可略过) https://blog.csdn.net/weixin_43944305/article/details/106152976 进行简单的清理 docker system df docker system df -v docker system prune2. 查看overlay2的占用空间&#xff0c; 找到对应的容器 https://blog.c…

Navicat Premium 16 for Mac/Win:数据库管理的全能之选

在数字化时代&#xff0c;数据库管理已成为各行各业不可或缺的一环。而Navicat Premium 16作为一款功能强大的数据库管理软件&#xff0c;无疑为数据库管理员和开发者提供了高效、便捷的解决方案。 Navicat Premium 16支持多种主流数据库系统&#xff0c;无论是MySQL、Postgre…

编程新手必看,Python3编程第一步语句学习(15)

介绍&#xff1a; 在开始编写Python 3程序之前&#xff0c;有一些基本步骤和概念需要了解。以下是开始Python 3编程之旅的第一步介绍&#xff1a; 安装Python&#xff1a; 访问Python官方网站 python.org 下载适合您操作系统的Python版本&#xff08;确保选择Python 3而非Pytho…

硕士毕业论文评审老师的评审标准

硕士毕业论文评审老师的评审标准通常涉及以下几个方面&#xff1a; 工作态度与努力&#xff1a;评审老师会考察学生在毕业论文工作期间是否表现出刻苦努力、态度认真的精神&#xff0c;并且是否遵守了各项相关纪律。 任务完成情况&#xff1a;学生是否能按时、全面、独立地完成…

JS - BOM(浏览器对象模型)

BOM 浏览器对象模型 BOM可以使我们通过JS来操作浏览器 在BOM中为我们提供了一组对象&#xff0c;用来完成对浏览器的操作 BOM对象 BOM&#xff08;Browser Object Model&#xff09;是指浏览器对象模型&#xff0c;它提供了与浏览器窗口进行交互的对象和方法。BOM包括一些核…

Linux系统——Zookeeper集群

目录 一、Zookeeper概述 1.Zookeeper简介 2.Zookeeper工作机制 3.Zookeeper数据结构 4.Zookeeper应用场景 4.1统一命名服务 4.2统一配置管理 4.3统一集群管理 4.4服务器动态上下线 4.5软负载均衡 5.Zookeeper选举机制 5.1第一次启动选举机制 5.2非第一次启动选举机…

【Unity】常见性能优化

1 前言 本文将介绍下常用的Unity自带的常用优化工具&#xff0c;并介绍部分常用优化方法。都是比较基础的内容。 2 界面 2.1 Statistics窗口 可以简单查看Unity运行时的统计数据&#xff0c;当前一帧的性能数据。 2.1.1 Audio 音频相关内容。 Level&#xff1a;音量大小&a…

图机器学习导论

图&#xff1a;描述关系数据的通用语言&#xff0c;起源于哥尼斯堡七桥问题 传统的机器学习&#xff1a;数据样本之间独立同分布&#xff0c;简单拟合数据边界&#xff0c;在传统的机器学习中&#xff0c;每个数据样本彼此无关。传统的神经网络&#xff0c;只能处理简单的表格、…

实体行业的品牌传播与网络运营,迅腾文化解决完善品牌定位运营

实体行业的品牌传播与网络运营&#xff0c;迅腾文化解决完善品牌定位运营 在今日的商业环境中&#xff0c;如何借助网络的力量&#xff0c;将品牌有效地传播出去&#xff0c;让渠道商、加盟商和消费者感受到安全感&#xff0c;成为了深思的问题。品牌是一个企业的灵魂&#xf…

《青少年成长管理2024》048 “成长目标:到哪儿了?”1/2

《青少年成长管理2024》048 “成长目标&#xff1a;到哪儿了&#xff1f;”1/2 一、神奇的地球二、群居的人类三、比较而存在四、竞争与合作五、等级和秩序 本节摘要&#xff1a;当你来到这个世界&#xff0c;首先认识一下这是一个什么样的世界&#xff0c;你处于一个什么样的环…

动态规划先导片

大家知道动规是由前一个状态推导出来的&#xff0c;而贪心是局部直接选最优的&#xff0c;对于刷题来说就够用了。 对于动态规划问题&#xff0c;我将拆解为如下五步曲&#xff0c;这五步都搞清楚了&#xff0c;才能说把动态规划真的掌握了&#xff01; 确定dp数组&#xff0…

linux造成只读模式的原因和解决方法

造成硬盘分区只读的可能原因有: 文件系统错误,内核相关硬件驱动bug,FW固件类问题,磁盘坏道 硬盘背板故障,硬盘线缆故障,HBA卡故障,RAID卡故障,随意开关机系统损坏 使用用 fsck – y /dev/sda (/dev/sda指你需要修复的分区) 来修复文件系统 mount -t vfat /dev/sda1…

开源!工厂数字化项目会用到的地理信息系统

软件介绍 QGIS&#xff08;Quantum GIS&#xff09;是一款免费、开源、跨平台的地理信息系统&#xff08;GIS&#xff09;软件&#xff0c;适用于Unix平台、Windows和MacOS。提供了强大且用户友好的功能&#xff0c;使其成为地理信息处理领域的热门选择。 功能特点 1.空间数据管…

react使用npm i @reduxjs/toolkit react-redux

npm i reduxjs/toolkit react-redux 创建一个 store文件夹&#xff0c;里面创建index.js文件和子模块文件夹 index,js文件写入以下代码 import {configureStore} from reduxjs/toolkit // 导入子模块 import counterReducer from ./modules/one import two from ./modules/tw…

鸿蒙TypeScript学习第14天:【联合类型】

1、TypeScript 联合类型 联合类型&#xff08;Union Types&#xff09;可以通过管道(|)将变量设置多种类型&#xff0c;赋值时可以根据设置的类型来赋值。 注意&#xff1a;只能赋值指定的类型&#xff0c;如果赋值其它类型就会报错。 创建联合类型的语法格式如下&#xff1…

【项目精讲】Spring框架中如何使用Redis+代码实现(2)利用Spring Cache框架

Spring Cache框架 Spring Cache 是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单地加一个注解&#xff0c;就能实现缓存功能。 Spring Cache 提供了一层抽象&#xff0c;底层可以切换不同的缓存实现&#xff0c;例如&#xff1a; EHCacheCaffeineRedi…

RTSP/Onvif安防视频EasyNVR平台 vs.多协议接入视频汇聚EasyCVR平台:设备分组的区别

EasyNVR安防视频云平台是旭帆科技TSINGSEE青犀旗下支持RTSP/Onvif协议接入的安防监控流媒体视频云平台。平台具备视频实时监控直播、云端录像、云存储、录像检索与回看、告警等视频能力&#xff0c;能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、W…

大厂Java笔试题之判断字母大小写

/*** 题目&#xff1a;如果一个由字母组成的字符串&#xff0c;首字母是大写&#xff0c;那么就统计该字符串中大写字母的数量&#xff0c;并输出该字符串中所有的大写字母。否则&#xff0c;就输出* 该字符串不是首字母大写*/ public class Demo2 {public static void main(St…

Redis的双写一致性问题

双写一致性问题 1.先删除缓存或者先删除数据库都可能出现脏数据。 2.删除两次缓存&#xff0c;可以在一定程度上降低脏数据的出现。 3.延时是因为数据库一般采用主从分离&#xff0c;读写分离。延迟一会是让主节点把数据同步到从节点。 1.读写锁保证数据的强一致性 因为一般放…

在视频号开店,新手一定要注意了,这几个细节很多人都不知道

大家好&#xff0c;我是电商笨笨熊 视频号小店作为今年黑马项目&#xff0c;自是吸引力不少的电商玩家&#xff1b; 但是在这些玩家中不免有一些新手玩家&#xff0c;从未做过电商&#xff0c;或者做过其他平台的电商但是没有接触过视频号&#xff1b; 而视频号小店在某些地…