【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小值. 输入输 ...
随机推荐
- Redux的核心概念,实现代码与应用示例
Redux是一种JavaScript的状态管理容器,是一个独立的状态管理库,可配合其它框架使用,比如React.引入Redux主要为了使JavaScript中数据管理的方便,易追踪,避免在大型的Jav ...
- Mysql数据库(三)Mysql表结构管理
一.MySQL数据类型 1.数字类型 (1)整数数据类型包括TINYINT/BIT/BOOL/SMALLINT/MEDIUMINT/INT/BIGINT (2)浮点数据类型包括FLOAT/DOUBLE ...
- 自定义segue的方向
花了挺久时间,终于通过google在stake overflow上找到了解决方式. 总结一下:重写一个custom的segue,在storyboard的右边设置segue为custom,并设置其对应的 ...
- swift ARC中的strong、weak、unowned
Swift 用自动引用计数ARC(Automatic Reference Counting)方式来跟踪和管理app的内存使用.这使得内存管理成为swift内部的机制,不需要认为考虑.ARC会自动释放那 ...
- Hibernate 查询方式、JPA查询方式
hibernate 查询方式: OID 查询 对象导航查询 HQL 方式查询 QBC方式查询 原生SQL方式查询 JPA 查询方式: OID 查询 对象导航查询 JPQL 方式查询 CriteriaB ...
- POI 生成 word 文档 简单版(包括文字、表格、图片、字体样式设置等)
POI 生成word 文档 一般有两种方法: ① word模板 生成word 文档 : ② 写代码直接生成 word 文档: 我这里演示的是第二种方法,即写代码生成 word文档,不多说废话,直接 ...
- python3 自己写的一个小算法(比对中文文本相似度)
函数使用说明: 函数的三个参数分别是“匹配语句”,“匹配语料”,“相关度”: 匹配语句,和匹配预料中的语句匹配的语句,必须为字符串: 匹配语料,被匹配语句来匹配的语句列表,必须为列表: 相关度,函数只 ...
- hack the box -- sizzle 渗透过程总结,之前对涉及到域内证书啥的还不怎么了解
把之前的笔记搬运过来 --- 1 开了443,用smbclient建立空连接查看共享 smbclient -N -L \\\\1.1.1.1 Department Shares Operatio ...
- [考试反思]0929csp-s模拟测试55:消逝
菜得过分. 面对T1的大板子不知所措,然后T2的贪心不小心把排序语句删了... T1这种大模板啊...其实我是觉得我能打出来的,然后先用一个小时码了一个2k. 然后做T2想贪心就出来了.十分钟码完T3 ...
- CSPS模拟 92
为什么每次我的flag都会倒? skyh:12:15之前你把T2改出来我吃屎. ----12:10 于是12:12把线段树打完 12:13把主函数打完,过样例,带着一个sb错误交了,WA飞. 然后我就 ...