洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]
可持久化线段树1(主席树)
题目背景
这是个非常经典的主席树入门题——静态区间第K小
数据已经过加强,请使用主席树。同时请注意常数优化
题目描述
如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值。
输入输出格式
输入格式:
第一行包含两个正整数N、M,分别表示序列的长度和查询的个数。
第二行包含N个正整数,表示这个序列各项的数字。
接下来M行每行包含三个整数 $l,r,k$ , 表示查询区间 $[l,r]$ 内的第k小值。
输出格式:
输出包含k行,每行1个正整数,依次表示每一次查询的结果
输入输出样例
5 5
25957 6405 15770 26287 26465
2 2 1
3 4 1
4 5 1
1 2 2
4 4 1
6405
15770
26287
25957
26287
说明
数据范围:
对于20%的数据满足: $1 \leq N, M \leq 10$
对于50%的数据满足: $1 \leq N, M \leq 10^3$
对于80%的数据满足: $1 \leq N, M \leq 10^5$
对于100%的数据满足: $1 \leq N, M \leq 2\cdot 10^5$
对于数列中的所有数 $a_i$ ,均满足 $-{10}^9 \leq a_i \leq {10}^9$
样例数据说明:
N=5,数列长度为5,数列从第一项开始依次为 $[25957,6405,15770,26287,26465]$
第一次查询为 $[2,2]$ 区间内的第一小值,即为6405
第二次查询为 $[3,4]$ 区间内的第一小值,即为15770
第三次查询为 $[4,5]$ 区间内的第一小值,即为26287
第四次查询为 $[1,2]$ 区间内的第二小值,即为25957
第五次查询为 $[4,4]$ 区间内的第一小值,即为26287
分析:
主席树入门题。
一直说要学习主席树来的,但是直到今天才实现。主席树的具体思想蒟蒻就不再赘述,只说下$k$小值查询如何实现。查询静态$k$小值的时候在主席树中存储的是一个权值,也就是说我们把这棵主席树当做一颗权值树。现将数据离散,然后按照原顺序依次插入线段树中,从根节点开始往下直到找到第该元素排名个数个的线段树中节点的位置,将沿途经过的每个节点的记录的值+1。这样的话根据线段树中的权值就可以用一种类似于平衡树查询$k$小值的方法来查询。具体实现看代码。
Code:
//It is made by HolseLee on 29th July 2018
//Luogu.org P3834
#include<bits/stdc++.h>
using namespace std; const int N=2e5+;
int n,m,tot,cnt,a[N],b[N],rk[N],rt[N];
struct President_tree{
int ls,rs,sum;
}t[N*]; int read()
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=(num<<)+(num<<)+ch-'';ch=getchar();}
return flag?-num:num;
} inline void build(int l,int r,int &node)
{
node=++cnt;
if(l==r)return ;
int mid=(l+r)>>;
build(l,mid,t[node].ls);
build(mid+,r,t[node].rs);
} inline void update(int l,int r,int &node,int last,int tar)
{
node=++cnt;t[node]=t[last];++t[node].sum;
if(l==r)return;
int mid=(l+r)>>;
if(tar<=mid)update(l,mid,t[node].ls,t[last].ls,tar);
else update(mid+,r,t[node].rs,t[last].rs,tar);
} inline int quary(int l,int r,int node,int last,int tar)
{
if(l==r)return a[l];
int now=t[t[node].ls].sum-t[t[last].ls].sum,mid=(l+r)>>;
if(tar<=now)return quary(l,mid,t[node].ls,t[last].ls,tar);
else return quary(mid+,r,t[node].rs,t[last].rs,tar-now);
} int main()
{
n=read();m=read();
for(int i=;i<=n;++i){
a[i]=read();b[i]=a[i];
}
sort(a+,a+n+);
tot=unique(a+,a+n+)-a-;
build(,tot,rt[]);
for(int i=;i<=n;++i)
rk[i]=lower_bound(a+,a+tot+,b[i])-a;
for(int i=;i<=n;i++)
update(,tot,rt[i],rt[i-],rk[i]);
int l,r,k;
for(int i=;i<=m;++i){
l=read();r=read();k=read();
printf("%d\n",quary(,tot,rt[r],rt[l-],k));
}
return ;
}
洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]的更多相关文章
- 【洛谷 P3834】 可持久化线段树1(主席树)
题目链接 主席树=可持久化权值线段树. 如果你不会可持久化线段树,请右转 如果你不会权值线段树,请自行脑补,就是线段树维护值域里有多少个数出现. 可持久化线段树是支持查询历史版本的. 我们对每个数都进 ...
- 洛谷.3834.[模板]可持久化线段树(主席树 静态区间第k小)
题目链接 //离散化后范围1~cnt不要错 #include<cstdio> #include<cctype> #include<algorithm> //#def ...
- 洛谷.3835.[模板]可持久化平衡树(fhq treap)
题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 【洛谷P3834】(模板)可持久化线段树 1(主席树)
[模板]可持久化线段树 1(主席树) https://www.luogu.org/problemnew/show/P3834 主席树支持历史查询,空间复杂度为O(nlogn),需要动态开点 本题用一个 ...
- 洛谷P3834【模板】可持久化线段树 1(主席树)
题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...
- HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
随机推荐
- 前端PHP入门-032-异常处理-应用级别
禁止显示错误 在php.ini配置文件中.我们可以控制php的错误显示状态. php.ini中有一个专门的配置项: display_errors 这个选项设置是否将错误信息输出到网页,或者对用户隐藏而 ...
- Dubbo 的应用
--- 用于大规模服务化,通过在消费方获取服务提供方的地址列表,实现负载均衡,减轻服务器压力. 最简单调用图 节点角色说明: l Provider: 暴露服务的服务提供方. l Consumer ...
- 也谈matlab中读取视频的一个重要函数mmreader
也谈matlab中读取视频的一个重要函数mmreader 在matlab中输入help mmreader来查阅一下该函数,有如下信息: MMREADER Create a multimedia rea ...
- 51nod1056 最长等差数列 V2
基准时间限制:8 秒 空间限制:131072 KB 分值: 1280 N个不同的正整数,从中选出一些数组成等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括 ...
- 【LibreOJ】#6257. 「CodePlus 2017 12 月赛」可做题2
[题意]数列满足an=an-1+an-2,n>=3.现在a1=i,a2=[l,r],要求满足ak%p=m的整数a2有多少个.10^18. [算法]数论(扩欧)+矩阵快速幂 [题解]定义fib(i ...
- 关于HttpWebRequest发生服务器协议冲突的解决办法
WinForm下的app.config文件中添加: <system.net> <settings> <httpWebRequest useUnsafeHe ...
- 【leetcode 简单】第十七题 x 的平方根
实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 输出: 2 示例 ...
- 从ZoomEye API 到 Weblogic 弱口令扫描
参考资料: ZoomEye API: https://www.zoomeye.org/api/doc Weblogic-Weakpassword-Scnner: https://github.com/ ...
- 快速幂取模_C++
一.题目背景 已知底数a,指数b,取模值mo 求ans = ab % mo 二.朴素算法(已知可跳过) ans = 1,循环从 i 到 b ,每次将 ans = ans * a % mo 时间复杂度O ...
- Anaconda3的安装和汉化
下载页面 : https://www.anaconda.com/download 直接下载(Windows) : Anaconda3-5.0.0-Windows-x86_64.exe | Anacon ...