可持久化线段树(主席树)快速简洁教程 图文并茂 保证学会。kth number例题
如果学不会也不要打我。
假设你会线段树
开始!
主席树也叫可持久化线段树
顾名思义,它能够保存线段树在每个时刻的版本。
什么叫每个时刻的版本?你可能对一棵普通线段树进行各种修改,这每种样子就是我们所说的不同时刻的版本。
假设我们对线段树进行单点修改,维护区间和。
每次修改操作中,只有logn个节点会被修改,我们可以复制这些被修改的节点,而不复制没有被改变的节点(以提高效率)。
最后通过特殊的方式建立出新时刻的树。
建造方式如下:
假设上一时刻的树长这样:

现在进行修改操作,对下标为3的位置修改,也就是说修改1 3 6号节点。若是普通线段树,则直接修改1 3 6三个节点。但是在主席树中,我们不直接在1 3 6号节点上修改。而是新建3个节点,分别对应1 3 6号节点,对新建节点进行本想在1 3 6号节点进行的操作(“本想”指普通线段树)。
如图:

关于不同版本的线段树理解
接上图,可以观察到,1号和8号往下分别是两棵不同版本的线段树,不同版本共用很多节点。这并不会影响自上而下的查询。
单点修改的例子

以下内容质量不高:
寒羽吾:
用主席树做kth number,就是在空线段树的基础上,依次在线段树的位置a[1]处加一,a[2]处加一。即用线段树维护值在某区间中的ai有多少个。然后可以在线段树上移动指针,找到第k个。
寒羽吾:
考虑区间[l,r]的限制,即r时刻的线段树减去l-1时刻的线段树,就得到维护ai(下标i在[l,r]中)的线段树了。
寒羽吾:
查询的时候不必真把做差得到的线段树求出来,需要这个线段树的什么位置就访问r版本和l-1版本的对应点,取出值相减即可。
寒羽吾:
上面是我写的板子,t表示树节点,w[0]左孩子w[1]右孩子。
寒羽吾:
理论上维护21e9个元素的线段树是开不下节点的(也是时间上不可建立的),但因为主席树的特殊性:只建立需要用(改变)的节点。所以可以不对ai进行离散化,直接建立“看似”能维护21e9个元素的线段树。
#include<bits/stdc++.h>
using namespace std;
struct node{
int sum;
int w[2];
}t[5000005];
int np;
int n,m;
int st[100005];
int a[100005];
void plu(int x,int c,int num){
int now=++np;
t[now]=t[x];
if(c<0){
t[now].sum++;
return;
}
int p=(num>>c)&1;
plu(t[now].w[p],c-1,num);
t[now].w[p]=now+1;
t[now].sum=t[t[now].w[0]].sum+t[t[now].w[1]].sum;
}
int solve(int l,int r,int k){
int lx=st[l-1],rx=st[r],ans=0;
for(int i=0;i<=30;i++){
int p=0;
if(t[t[rx].w[0]].sum-t[t[lx].w[0]].sum<k)
k-=t[t[rx].w[0]].sum-t[t[lx].w[0]].sum,
p=1;
lx=t[lx].w[p],
rx=t[rx].w[p],
ans=ans<<1|p;
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]+=1e9;
}
np=1;st[0]=1;
for(int i=1;i<=n;i++){
st[i]=np+1;
plu(st[i-1],30,a[i]);
}
for(int i=1;i<=m;i++){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",int(solve(l,r,k)-1e9));
}
return 0;
}
可持久化线段树(主席树)快速简洁教程 图文并茂 保证学会。kth number例题的更多相关文章
- 线段树简单入门 (含普通线段树, zkw线段树, 主席树)
线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...
- 权值线段树&&可持久化线段树&&主席树
权值线段树 顾名思义,就是以权值为下标建立的线段树. 现在让我们来考虑考虑上面那句话的产生的三个小问题: 1. 如果说权值作为下标了,那这颗线段树里存什么呢? ----- 这颗线段树中, 记录每个值出 ...
- [学习笔记] 可持久化线段树&主席树
众所周知,线段树是一个非常好用也好写的数据结构, 因此,我们今天的前置技能:线段树. 然而,可持久化到底是什么东西? 别急,我们一步一步来... step 1 首先,一道简化的模型: 给定一个长度为\ ...
- 【数据结构模版】可持久化线段树 && 主席树
浙江集训Day4,从早8:00懵B到晚21:00,只搞懂了可持久化线段树以及主席树的板子.今天只能记个大概,以后详细完善讲解. 可持久化线段树指的是一种基于线段树的可回溯历史状态的数据结构.我们想要保 ...
- 洛谷P3834 可持久化线段树(主席树)模板
题目:https://www.luogu.org/problemnew/show/P3834 无法忍受了,我要写主席树! 解决区间第 k 大查询问题,可以用主席树,像前缀和一样建立 n 棵前缀区间的权 ...
- 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小值. 输入输 ...
- 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))
函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...
随机推荐
- 向一个GitHub repository添加协作者
第一步: 在协作者的机器(就是你的电脑啦)上创建一个ssh key (使用命令ssh-keygen) 第二步: 创建一个github账户 第三步: 把public-key添加到你的github用户账户 ...
- SpringMVC 源码阅读
- [linux] uptime 命令中关于平均负载的解释
1.当前时间 00:13:25 2.系统已运行的时间 9小时19分 3.当前在线用户 2 user 4.平均负载:0.17, 0.12, 0.07 最近1分钟.5分钟.15分钟系统的负载 为了更好地理 ...
- 几个免费 IP 归属地查询 API
1.淘宝:同个IP不能连续查询,需要时间间隔 http://ip.taobao.com/service/getIpInfo.php?ip=114.114.114.114 返回结果 { "co ...
- SVM 之 MATLAB 实现代码
MATLAB 中 SVM 实现 直接上代码 main.m %% Initialize data clear, clc, close all; load('data.mat'); y(y == 0) = ...
- 【防火墙】iptables查看、添加、删除规则
root@ROUTER:~# iptables -t -nvL 查看到当前我的端口映射下有很多规则. 1.删除端口映射规则和端口映射的链 ①先删除子链里的所有规则 iptables -t nat -F ...
- Path类 操作文件类
// Path类 IO命名空间 静态类 不能创建对象类名. string str =@"E:\C#程序设计基础入门教程\(第十一天)\122\22\nee.txt"; ////in ...
- 清理widows的网络连接
在听兄弟连李明老师的课程时,Samba配置时,window连接有时要清理,可以用以下命令 1.打开win的命令行. 2.输入net use,就会打印出当前缓存的连接上列表. 3.根据列表,一个个删除连 ...
- JavaScript (预热)
希望把某个元素移除你的视线: 1.display:none; 显示为无 2.visibility:hidden; 隐藏 3.width\height; 4.透明度: 5.left\top; 6.拿 ...
- SVM个人学习总结
SVM个人学习总结 如题,本文是对SVM学习总结,主要目的是梳理SVM推导过程,以及记录一些个人理解. 1.主要参考资料 [1]Corres C. Support vector networks[J] ...