【Luogu P3834】可持久化线段树(主席树)
Luogu P3834
可持久化数据结构就是支持在历史版本上进行查询和修改操作的数据结构。
主席树就是对线段树的改进,使之可持久化。
前置知识:动态开点线段树
我们利用权值(值域)线段树统计区间内的数出现的次数。
(权值线段树类似于线段树+桶)
那么我们可以对每一个位置建立一棵线段树,维护\(1\)~\(i\)的数据在一个区间上出现的次数。
求\(a[l...r]\)第k小,可以令第\(r\)棵线段树在区间\([x,y]\)上出现的次数减去上第\(l-1\)棵的线段树在区间\([x,y]\)上出现的次数,这样就可以得出\(a[l...r]\)在区间\([x,y]\)上出现的次数,如果次数小于\(k\),那么说明第\(k\)大在相邻的下一个区间。
事实上我们不可能对每个位置建立线段树,否则一定会MLE,所以对于这个版本相对于上一个版本没有改变过的节点,我们可以直接使用上一个版本的节点。
结合代码进行理解:
#include<cstdio>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
const int maxn=2e5;
int tot,tree[maxn<<5],ls[maxn<<5],rs[maxn<<5],n,m,a[maxn],b[maxn],rt[maxn],l,r,k;
//rt[]为各个版本的根节点,ls[]为节点的左儿子,rs[]为节点的右儿子
int build(int l,int r)
{
int now=++tot;
if (l==r)
{
tree[now]++;
return now;
}
ls[now]=build(l,mid);
rs[now]=build(mid+1,r);
return now;
}
int update(int root,int l,int r,int pnt)
{
int now=++tot;//新建节点
if (l<=pnt&&pnt<=r)
{
tree[now]=tree[root]+1;//继承信息
ls[now]=ls[root];
rs[now]=rs[root];
//记录左右儿子,假设可以直接使用上一个版本的节点
}
if (l==r) return now;
if (mid>=pnt) ls[now]=update(ls[now],l,mid,pnt);
else rs[now]=update(rs[now],mid+1,r,pnt);
//更新,并更换儿子节点编号
return now;
}
int query(int u,int v,int l,int r,int k)
{
if (l==r) return l;
int tmp=tree[ls[v]]-tree[ls[u]];//计算左区间出现次数
if (tmp>=k) return query(ls[u],ls[v],l,mid,k);
else return query(rs[u],rs[v],mid+1,r,k-tmp);//不在
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];//保存副本供离散化使用
}
sort(b+1,b+1+n);
int newend=unique(b+1,b+1+n)-b-1;
rt[0]=build(1,newend);//首先建立一个空的线段树
for (int i=1;i<=n;i++)
{
int loc=lower_bound(b+1,b+1+newend,a[i])-b;
rt[i]=update(rt[i-1],1,newend,loc);//更新,记录新版本的根节点
}
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&l,&r,&k);
int loc=query(rt[l-1],rt[r],1,newend,k);
printf("%d\n",b[loc]);
}
return 0;
}
【Luogu P3834】可持久化线段树(主席树)的更多相关文章
- 线段树简单入门 (含普通线段树, zkw线段树, 主席树)
线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...
- [Luogu 3701] 「伪模板」主席树
[Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ...
- 洛谷P3834 可持久化线段树(主席树)模板
题目:https://www.luogu.org/problemnew/show/P3834 无法忍受了,我要写主席树! 解决区间第 k 大查询问题,可以用主席树,像前缀和一样建立 n 棵前缀区间的权 ...
- 洛谷 [P3834] 可持久化线段树(主席树)
主席树可以存储线段树的历史状态,空间消耗很大,一般开45n即可 #include <iostream> #include <cstdio> #include <cstri ...
- [学习笔记] 可持久化线段树&主席树
众所周知,线段树是一个非常好用也好写的数据结构, 因此,我们今天的前置技能:线段树. 然而,可持久化到底是什么东西? 别急,我们一步一步来... step 1 首先,一道简化的模型: 给定一个长度为\ ...
- 权值线段树&&可持久化线段树&&主席树
权值线段树 顾名思义,就是以权值为下标建立的线段树. 现在让我们来考虑考虑上面那句话的产生的三个小问题: 1. 如果说权值作为下标了,那这颗线段树里存什么呢? ----- 这颗线段树中, 记录每个值出 ...
- 【数据结构模版】可持久化线段树 && 主席树
浙江集训Day4,从早8:00懵B到晚21:00,只搞懂了可持久化线段树以及主席树的板子.今天只能记个大概,以后详细完善讲解. 可持久化线段树指的是一种基于线段树的可回溯历史状态的数据结构.我们想要保 ...
- bzoj 4408: [Fjoi 2016]神秘数 数学 可持久化线段树 主席树
https://www.lydsy.com/JudgeOnline/problem.php?id=4299 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1 ...
- 牛客网 暑期ACM多校训练营(第一场)J.Different Integers-区间两侧不同数字的个数-离线树状数组 or 可持久化线段树(主席树)
J.Different Integers 题意就是给你l,r,问你在区间两侧的[1,l]和[r,n]中,不同数的个数. 两种思路: 1.将数组长度扩大两倍,for(int i=n+1;i<=2* ...
- [POJ2104] K – th Number (可持久化线段树 主席树)
题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...
随机推荐
- Kerberos kinit crontab定时任务不生效的问题解决
问题 有这样一个定时任务 1 */12 * * * kinit -kt xxxxxx.keytab principle 这样写每天 12点,执行一次. 但是服务器的应用程序报错: GSS initia ...
- 小白学 Python(12):基础数据结构(字典)(上)
人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...
- django-模板之extends(三)
/book/base.html <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- 数据库系统(六)---MySQL语句及存储过程
一.DDL.DML.DCL常用语句 1.DDL(Data Definition Language)数据库定义语言 (1)数据库模式定义 #创建数据库 create database if exsite ...
- [翻译]Jupyter notebook .NET Core 内核预览1
当您想到Jupyter Notebooks时,您可能会考虑使用Python,R,Julia或Scala而不是.NET编写代码. 今天,我们很高兴宣布您可以在Jupyter Notebooks中编写.N ...
- MYSQL结构修改
mysql改表结构主要是5大操作 ADD 添加字段 MODIFY 修改字段类型 CHANGE 修改字段名(也可以修改字段名) DROP 删除字段 RENAME 修改表名 ADD添加新字段:(新字段默认 ...
- Python基础语法,他其实很贵!
# -*- coding:utf-8 -*- # @Time :2019/7/19 11:26# @Author :ITester# @Email :1036881587@qq.com# @File ...
- day 1 堆 hash 线段树 树状数组 冰茶姬 字典树 二叉查找树
来郑州的第二天,早上开始也没说什么就说了些注意安全,各种各样的注意安全... 冰茶姬: 原来再打食物链时看了一下冰茶姬,只注意了路径压缩,没想到还有什么按秩排序但确实快了不少... int find( ...
- 学习笔记 : python 文件操作
1.如果文件路径带有 \ 比如 open('c:\python\test.txt') 会报:SyntaxError: (unicode error) 'unicodeescape' codec ...
- dianFanEditor Web在线编辑器
个人很喜欢kodexplorer 的在线编辑器.苦于没有加载FTP目录的功能. 索性自己改造了一下,用.NET 做了几个WEB接口,用CEF3做浏览器内核,打包了在线地址做编辑器. 即可加载本地磁盘, ...