【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小值. 输入输 ...
随机推荐
- python之ORM(对象关系映射)
实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,而不需要更改代码.orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句.所有使用Django开发的项目无需关心程序底层使用的 ...
- 外星人R7 1080Ti 装ubuntu两个巨坑
机器型号(Alienware R7):GTX1080ti,i7-8700 install ubuntu 16.04 坑一 ACPI Error: Namespace lookup failure AC ...
- 暑期集训20190725 胜地不常(paradise)
[题目描述] 给定两个长度为n的非负整数数组a,b, [输入数据] 第一行一个整数n. 第二行n个整数a1~an. 第三行n个整数b1~bn. [输出数据] 一行一个整数表示答案. [样例输入] 4 ...
- 洛谷P5520 【[yLOI2019] 青原樱】
这题是小学奥数啊. 题意:求\(m\)个不同物品两两不相邻的方案数. 直接排列组合. 我们可以减掉他们之间最少需要空出来的位数--\(m-1\)个空位 像这样,我们只用留\(m-1\)个空位放在每两个 ...
- 学习笔记27_Action方法技巧
*在Action方法中,会存在重载问题,名字冲突就会报错,使用 [HttpPost]//只接受Post请求,且级别较高 public ActionResult Edit(..){} *在Action方 ...
- 【ObjectC—浅copy和深copy】
一.OC设计copy的目的 为了能够从源对象copy一个新的对象副本,改变新对象(副本)的时候,不会影响到原来的对象. 二.实现copy协议 OC提供了两种copy方法:copy和mutableCop ...
- python私有变量的分类
- 爬虫之request库主要解析---参照慕课北理工嵩天
kv = {'key1':'value1','key2':'value2'} r = requests.request (' GET' , 'http://python123.io/ws' , par ...
- 8.3 NOIP 模拟12题解
话说这次考试T1和T2是真的水,然而T1CE,T2TLE,T3CE 这不就是在侮辱我的智商啊!之前本机编译都是c++,以后要用c++11. 这次的T1就是一个大型找规律,我的规律都找出来了,但是竟然用 ...
- Java环境变量配置教程
Windows 10 Java环境变量配置教程 目前Windows 10系统已经很成熟,大多数人开发都在Windows 10系统下进行开发,于是乎我做一下Java环境变量在Windows 10配下的 ...