给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个.

"静态"指的是不带修改.

这个问题有多种做法:

1. 归并排序

POJ 2104, 静态区间第K小

 #include <bits/stdc++.h>
using namespace std; const int N(1e5+);
int a[][N]; void merge(int id, int b, int e){
int mid=(b+e)>>;
for(int l=b, r=mid, i=b; i<e; i++){
if(l==mid) a[id][i]=a[id+][r++];
else if(r==e) a[id][i]=a[id+][l++];
else if(a[id+][l]<=a[id+][r]) a[id][i]=a[id+][l++];
else a[id][i]=a[id+][r++];
}
} void build(int id, int b, int e){
if(b+==e){
scanf("%d", a[id]+b);
return;
}
int mid=(b+e)>>;
build(id+, b, mid);
build(id+, mid, e);
merge(id, b, e);
}
//返回k在[l, r)与[L, R)交集上的Rank
int Rank(int id, int L, int R, int l, int r, int k){
if(l<=L&&R<=r){
return lower_bound(a[id]+L, a[id]+R, k)-a[id]-L;
}
int mid=(L+R)>>;
if(r<=mid){
return Rank(id+, L, mid, l, r, k);
}
if(l>=mid){
return Rank(id+, mid, R, l, r, k);
}
return Rank(id+, L, mid, l, r, k)+Rank(id+, mid, R, l, r, k);
}
//返回(l, r]中Rank(x)>=k的最小的x
int BS(int b, int e, int k, int n){
int l=-1e9-, r=1e9+, mid;
while(r-l>){
mid=(l+r)>>;
if(Rank(, , n, b, e, mid)>=k) r=mid;
else l=mid;
}
return r;
}
int main(){
int n, m; scanf("%d%d", &n, &m);
build(, , n);
for(int l, r, k; m--;){
scanf("%d%d%d", &l, &r, &k), l--;
printf("%d\n", BS(l, r, k, n)-);
}
}

这种做法的想法是将归并排序的过程记录下来, 这样就形成了一棵线段树, 这棵线段树的每个节点记录着它所代表的那个区间[L,R]排好序后的情形.

我们把这样的线段树称做归并排序树, 归并排序树能在$O(\log^2{N})$的复杂度内完成如下查询:

$\text{RANK}(l, r, x)$: 区间$[l,r]$内小于$x$的数的数目.

定义$\text{LEAST}(l, r, k)$为区间$[l,r]$上第$k$小的数, 则有

$\text{LEAST}(l, r, k) = \max \{x \mid \text{RANK}(l, r, x)<k\}$

因而对于询问$\text{LEAST}(l, r, x)$, 我们可以二分答案 $x$ + $\text{RANK}(l, r, x)$判断, 从而在$O(\log{M}\log^2{N})$的复杂度内完成查询, 其中$M$是元素的范围, $N$是区间总长度. 当然, 我们也可以现将数组$A[1\cdots N]$排序, 付出一个$O(N\log{N}$)的预处理复杂度, 然后便可做到单次查询$O(\log^3{N})$.

但我觉得这个复杂度还是太高了, (归并排序)这种做法应该还有优化的可能性, 有待研究.

2. 划分树

数据结构2 静态区间第K大/第K小的更多相关文章

  1. 无序数组求第k大/第k小的数

    根据http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html 博客中所总结的7种解法,我挑了其中的解法3和解法6进行了实现. 解法3: ...

  2. POJ 2104 静态找区间第k大

    静态区间第k大的问题,往往可以利用主席树来解决 这是主席树的第一道题 主席树大概可以理解为在n个节点上都建立一棵线段树,但是想想会超出内存 每一个节点保存的线段树都记录当前整段前缀区间的信息 但是因为 ...

  3. HDU3473--Minimum Sum(静态区间第k大)

    Minimum Sum Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  4. 主席树初步学习笔记(可持久化数组?静态区间第k大?)

    我接触 OI也快1年了,然而只写了3篇博客...(而且还是从DP跳到了主席树),不知道我这个机房吊车尾什么时候才能摸到大佬们的脚后跟orz... 前言:主席树这个东西,可以说是一种非常畸形的数据结构( ...

  5. poj2104&&poj2761 (主席树&&划分树)主席树静态区间第k大模板

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 43315   Accepted: 14296 Ca ...

  6. 静态区间第k大(主席树)

    POJ 2104为例(主席树入门题) 思想: 可持久化线段树,也叫作函数式线段树,也叫主席树(高大上). 可持久化数据结构(Persistent data structure):利用函数式编程的思想使 ...

  7. 静态区间第k大(归并树)

    POJ 2104为例 思想: 利用归并排序的思想: 建树过程和归并排序类似,每个数列都是子树序列的合并与排序. 查询过程,如果所查询区间完全包含在当前区间中,则直接返回当前区间内小于所求数的元素个数, ...

  8. 主席树学习笔记(静态区间第k大)

    题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输出 ...

  9. 主席树(静态区间第k大)

    前言 如果要求一些数中的第k大值,怎么做? 可以先就这些数离散化,用线段树记录每个数字出现了多少次. ... 那么考虑用类似的方法来求静态区间第k大. 原理 假设现在要有一些数 我们可以对于每个数都建 ...

随机推荐

  1. 求最长回文子串 - leetcode 5. Longest Palindromic Substring

    写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...

  2. .Net 程序集按需加载机制

    在开始本文之前先提两个疑问: 1.一个.Net程序依赖很多的dll,那个他们是在应用程序启动的时候全部把所依赖的动态库全部都加载到应用程序域中的呢还是有选择的加载呢? 2.当应用程序已经启动后我们动态 ...

  3. JQuery功能查询页

    JQuery在前端开发中已经是常用的不能再常用的库了.最近的项目中使用到了JQuery,我第一次接触它的时候为了学习,把常用的操作指令用比较小的字体写在一页word上,打印出来贴在桌子上,用来让自己时 ...

  4. 使用spring boot和thrift、zookeeper建立微服务

    Spring cloud适应于云端服务,也适用于企业信息化SOA建设.spring boot也是restful微服务开发的利器.但对于内网服务,即服务与服务之间的调用,spring并没有去刻意封装,也 ...

  5. MyBatis学习--mybatis开发dao的方法

    简介 使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法. 主要概念介绍: MyBatis中进行Dao开发时候有几个重要的类,它们是SqlSessionFac ...

  6. 使用D3绘制图表(3)--添加坐标轴和文本标签

    上一篇是曲线的绘制,这样仅仅只是有一条线,完全先是不出数据想要表现的内容,于是我们要添加坐标系,添加坐标系和画线类似. 1.还是没有变化的html页面 <!DOCTYPE html> &l ...

  7. bootstrap实现pc屏幕五等分

    <!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  8. 100722B

    在stack里套set,然后每次根据他的操作,在set里操作,把括号hash,插入,输出set的size-1 #include<iostream> #include<set> ...

  9. HTTP协议学习---(七)代理

    本文介绍一些HTTP代理服务器的概念和工作原理 阅读目录 什么是代理服务器 Fiddler就是个典型的代理 代理作用一:FQ 代理作用二:匿名访问 代理作用三:通过代理上网 代理作用四:通过代理缓存, ...

  10. 常用jquery片断

    **1.检测Internet Explorer版本** 当涉及到CSS设计时,对开发者和设计者而言Internet Explorer一直是个问题.尽管IE6的黑暗时代已经过去,IE也越来越不流行,它始 ...