K-th Number
Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 35653   Accepted: 11382
Case Time Limit: 2000MS

Description

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. 
That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?" 
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.

Input

The first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000). 
The second line contains n different integer numbers not exceeding 109 by their absolute values --- the array for which the answers should be given. 
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).

Output

For each question output the answer to it --- the k-th number in sorted a[i...j] segment.

Sample Input

7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3

Sample Output

5
6
3

Hint

This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.

Source

Northeastern Europe 2004, Northern Subregion

 
  划分树,经典题
  关于划分树的解释可以参考博文:sdut 2610:Boring Counting(第四届山东省省赛原题,划分树 + 二分)。这个属于高级点的应用,至于基础的介绍,我就不多写了(懒人一个。。),可以参考这篇博客,介绍的很详细:划分树
  这里简单一提,划分树的主要作用是用来求“区间内第k大的元素”,这道题属于经典应用,就是赤裸裸的求一个区间内第k大的数。题目“K-th Number”已经标明了这种含义。
  因为之前做过一道划分树的题,所以无耻的套用了上道题的代码,然后就改了改就无耻的过了。O_o,原谅我吧。
  代码
 #include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define MAXN 100005
struct Divide_tree{ //划分树的结构(4个数组,2个操作)
int arr[MAXN]; //原数组
int sorted[MAXN]; //排序后数组
int sum[][MAXN]; //记录第i层1~j划分到左子树的元素个数(包括j)
int dat[][MAXN]; //记录第i层元素序列
void build(int c,int L,int R) //建树,主要是建立sum[][]和dat[][]数组
{
int mid = (L+R)>>;
int lsame = mid-L+; //lsame用来记录和中间值val_mid相等的,且可以分到左孩子的数的个数
//简单来说就是可以放入左孩子的,与中间值val_mid相等的数的个数
int lp=L,rp=mid+; //当前节点的左孩子和右孩子存数的起点
for(int i=L;i<mid;i++) //获得一开始的lsame
if(sorted[i]<sorted[mid])
lsame--;
for(int i=L;i<=R;i++){ //从前往后遍历一遍,
//确定当前节点区间内的所有元素的归属(放在左孩子或者放在右孩子)
if(i==L) sum[c][i]=;
else sum[c][i]=sum[c][i-];
if(dat[c][i]<sorted[mid]){ //当前元素比中间值val_mid小,放入左孩子
dat[c+][lp++] = dat[c][i];
sum[c][i]++;
}
else if(dat[c][i]>sorted[mid]) //当前元素比中间值val_mid大,放入右孩子
dat[c+][rp++] = dat[c][i];
else{ //当前元素值与中间值val_mid相等,根据lsame数判断放入左孩子还是右孩子
if(lsame){
lsame--;
sum[c][i]++;
dat[c+][lp++]=sorted[mid];
}
else{
dat[c+][rp++]=sorted[mid];
}
}
}
if(L==R) return ; //递归出口,遇到叶子节点
build(c+,L,mid); //递归进入左孩子区间
build(c+,mid+,R); //递归进入右孩子区间
}
int query(int c,int L,int R,int ql,int qr,int k)
{
//c为树的层数,L,R为当前节点的区间范围,ql,qr为查询的区间范围,k为查询范围内第k大的数
if(L==R) //递归出口,返回第k大的数
return dat[c][L];
int s; //记录[L,ql-1]中进入左孩子的元素的个数
int ss; //记录[ql,qr]中进入左孩子的元素的个数
int mid=(L+R)>>;
if(L==ql){ //端点重合的情况,单独考虑
s=;
ss=sum[c][qr];
}
else {
s=sum[c][ql-];
ss=sum[c][qr]-s;
}
if(k<=ss) //左孩子的元素个数大于k个,说明第k大的元素一定在左孩子区间中,到左孩子中查询
return query(c+,L,mid,L+s,L+s+ss-,k);
else
return query(c+,mid+,R,mid++ql-s-L,mid++qr-s-ss-L,k-ss);
}
};
Divide_tree tree; //定义划分树
int main()
{
int i,L,R,N,M,k;
scanf("%d%d",&N,&M);
for(i=;i<=N;i++){ //输入
scanf("%d",&tree.arr[i]);
tree.sorted[i]=tree.dat[][i]=tree.arr[i];
}
sort(tree.sorted+,tree.sorted+N+);
tree.build(,,N);
for(i=;i<=M;i++){ //M次询问
scanf("%d%d%d",&L,&R,&k);
printf("%d\n",tree.query(,,N,L,R,k));
} return ;
}

poj 2104:K-th Number(划分树,经典题)的更多相关文章

  1. 【POJ 2104】 K-th Number 主席树模板题

    达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没 ...

  2. POJ2104 K-th Number 划分树 模板题啊

    /*Source Code Problem: 2104 User: 96655 Memory: 14808K Time: 1282MS Language: G++ Result: Accepted S ...

  3. poj 2104 K-th Number 划分树,主席树讲解

    K-th Number Input The first line of the input file contains n --- the size of the array, and m --- t ...

  4. [hdu2665]Kth number(划分树求区间第k大)

    解题关键:划分树模板题. #include<cstdio> #include<cstring> #include<algorithm> #include<cs ...

  5. 静态区间第k大(划分树)

    POJ 2104为例[经典划分树问题] 思想: 利用快速排序思想, 建树时将区间内的值与区间中值相比,小于则放入左子树,大于则放入右子树,如果相等则放入左子树直到放满区间一半. 查询时,在建树过程中利 ...

  6. HDU-2665-Kth number(划分树)

    Problem Description Give you a sequence and ask you the kth big number of a inteval.   Input The fir ...

  7. [NBUT 1458 Teemo]区间第k大问题,划分树

    裸的区间第k大问题,划分树搞起. #pragma comment(linker, "/STACK:10240000") #include <map> #include ...

  8. poj 2104 K-th Number (划分树入门 或者 主席树入门)

    题意:给n个数,m次询问,每次询问L到R中第k小的数是哪个 算法1:划分树 #include<cstdio> #include<cstring> #include<alg ...

  9. POJ 2104 K-th Number(划分树)

    题目链接 参考HH大神的模版.对其中一些转移,还没想清楚,大体明白上是怎么回事了,划分树就是类似快排,但有点点区别的.多做几个题,慢慢理解. #include <cstdio> #incl ...

  10. hdu 2665 Kth number (poj 2104 K-th Number) 划分树

    划分树的基本功能是,对一个给定的数组,求区间[l,r]内的第k大(小)数. 划分树的基本思想是分治,每次查询复杂度为O(log(n)),n是数组规模. 具体原理见http://baike.baidu. ...

随机推荐

  1. webpack的最简单应用,只使用js与css的打包

    首先进行全局安装webpack npm install -g webpack cmd跳转到项目的文件夹,安装webpack npm install --save-dev webpack 接着需要pac ...

  2. Apache Thrift 服务开发框架学习记录

    Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架. 前言: 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Servic ...

  3. json_decode()和json_encode()的使用方法

    json_decode对JSON格式的字符串进行编码 json_encode对变量进行 JSON 编码 JS中对JSON的解析 一.JSON字符串转换为JSON对象     要运用上面的str1,必须 ...

  4. BurpSuite使用设置

    一.设置字体 二.设置字符集 三.设置浏览器代理 四.BurpSuite访问步骤 五.在Target中可以查看截获的数据包

  5. linux命令——mutt的安装和使用【转】

    linux命令--mutt的安装和使用[转] 首先介绍一下mutt这个软件,它是一款基于文字界面的邮件客户端,非常小巧,但功能强大,可以用它来读写,回复保存和删除你的邮件,能在linux命令行模式下收 ...

  6. php for循环建数据

    $data = []; ; $i<; $i++) { $data[] = $i; } print_r($data); 执行后打印的结果为: Array ( [] => [] => [ ...

  7. Android自定义图形shape

    在Android开发过程中,经常需要改变控件的默认样式, 那么通常会使用多个图片来解决.不过这种方式可能需要多个图片,比如一个按钮,需要点击时的式样图片,默认的式样图片. 这样就容易使apk变大.另一 ...

  8. Unity3d《Shader篇》Logo闪光特效

    Shader "Custom/Flash" { Properties { _MainTex ("Base (RGB)", 2D) = "white&q ...

  9. ABAP 内表的行列转换-发货通知单-SLIS

    REPORT Z_TEST_COL_TO_ROW. TYPE-POOLS: slis. TABLES: VTTP,LIPS,LIKP,KNA1 ,VTTK. DATA: gd_fieldcat TYP ...

  10. Effective C++ -----条款15:在资源管理类中提供对原始资源的访问

    APIs往往要求访问原始资源(raw resources),所以每一个RAII class应该提供一个“取得其所管理之资源”的办法. 对原始资源的访问可能经由显示转换(.get()成员函数或者指针取值 ...