K-th Number
Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 47066   Accepted: 15743
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
题意:给你有n个元素的数组,q次查询,每次问L,R之间第k大的数是什么。
 
思路:
划分树模板题。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1000000001
#define MOD 1000000007
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pi acos(-1.0)
using namespace std;
const int MAXN = ;
int num[][MAXN],cnt[][MAXN];//num[d][i]表示深度为d第i个数 cnt[d][i]表示深度为d第i个数之前(包括第i个数)小于sor[m]的个数
int n,sor[MAXN];//sor[i]表示快排后的数组
void build(int l,int r,int d)
{
if(l == r){
return ;
}
int m = (l + r) >> ;
int same_m = m - l + ;//same_m表示在[l,r]中和sor[m]相同值得个数 如果有多个sor[m]的值,那么有一部分会放到左孩子。
//这里就是求放到左孩子的值为sor[m]的个数
for(int i = l; i <= r; i++){
if(num[d][i] < sor[m])same_m --;
}
int pl,pr;
int cnt_small = ;//表示当前小于sor[m]的个数
pl = l,pr = m + ;//左右孩子开始的位置
for(int i = l; i <= r; i++){
if(num[d][i] < sor[m]){//如果当前值比sor[m]小 那么会放在左孩子
num[d+][pl++] = num[d][i];
cnt_small ++;
cnt[d][i] = cnt_small;
}
else if(num[d][i] == sor[m] && same_m){//如果当前的值和sor[m]相同,那么就要判断左边的sor[m]是否放满了
same_m --;
cnt_small ++;
cnt[d][i] = cnt_small;
num[d+][pl++] = num[d][i];
}
else {//放右孩子 由于右孩子都比sor[m]大,所以cnt_small不需要加
num[d+][pr++] = num[d][i];
cnt[d][i] = cnt_small;
}
}
build(l,m,d + );
build(m + ,r,d + );
}
void Init()
{
memset(cnt,,sizeof(cnt));
sort(sor+,sor+n+);
build(,n,);
}
int query(int L,int R,int k,int l,int r,int d)//查询区间[L,R]中第K大的值
{
if(l == r){//找到
return num[d][l];
}
int m = (l + r) >> ;
int s, ss;//s表示[l,L)中小于sor[m]的个数 ss表示[L,R]中小于sor[m]的个数
if(l == L)s = ;//如果左边界相同 不能cnt[d][L-1] 因为L-1有可能是别的子树的
else s = cnt[d][L - ];
ss = cnt[d][R] - s;
if(ss >= k){//如果当前区间内左孩子的个数足够k个,那么就要进入左孩子查询
int newl = l + s;//左边会变成l + s 因为左孩子的值都小于sor[m] 建树的时候,数组的相对大小顺序没有改变,也就是说这是一个稳定的排序。
//也就是说从d到d+1时 加入的数 还是按照相对顺序的
//所以这里的新的左边界 就是l + s, 我们要找的d+1层中 左孩子都是小于sor[m]的!!
// s是[l,L)的到左孩子的值, 看) 所以不需要减一
int newr = l + s + ss - ;//同理 不过由于这里 s + ss后就是[l,R] 连起来了 所以需要减一
return query(newl,newr,k,l,m,d + );
}
else {
int a = L - l - s;//不需要加一 因为L这里不算 所以后面的newl需要加1
//a表示[l,L)之间大于sor[m]的个数 也就是要进入右孩子的个数
int b = R - L + - ss;//b表示[L,R]之间 进入右孩子的个数
int newl = m + + a;//右孩子的值都大于sor[m] 所以原来的左边界 在右孩子中会变成 m + 1 + a
int newr = m + a + b;//b是长度 由于m本需要+1 但是由于加了长度就已经+1了 其实是 m + 1 + a + b - 1
return query(newl,newr,k - ss,m + ,r,d + );
}
}
void solve(int q)
{
int x,y,k;
while(q--){
scanf("%d%d%d",&x,&y,&k);
printf("%d\n",query(x,y,k,,n,));
}
}
int main()
{
int q;
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&q);
memset(num,,sizeof(num));
for(int i = ; i <= n; i++){
scanf("%d",&num[][i]);
sor[i] = num[][i];
}
Init();
solve(q);
}
return ;
}

hdu2665 && poj2104划分树的更多相关文章

  1. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  2. poj2104 划分树 区间K大 在线 无修改

    博主sbit....对于高级数据结构深感无力,然后这些东西在OI竟然烂大街了,不搞就整个人都不好了呢. 于是我勇猛的跳进了这个大坑 ——sbit 区间K大的裸题,在线,无修改. 可以用归并树(\(O( ...

  3. 初学划分树,小见解之!POJ-2104/HDU-2665

    划分树 本来是学主席树的,可怜我等巨弱观群巨博客难解fotle主席的思想精髓.于是学了一下划分树,嗯,花了一下午时间理解build(其实自己模拟一遍就通了),我很难理解为什么划分树会看不懂而能学会主席 ...

  4. 划分树(poj2104)

    poj2104 题意:给出n个数,有m次查询,每次查询要你找出 l 到 r 中第 k 大的数: 思路:划分树模板题 上述图片展现了查询时如何往下递推的过程 其中ly表示 [sl,l) 中有多少个数进入 ...

  5. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

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

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

  7. poj2104 线段树 划分树

    学习:http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html 划分树的build: 划分树是分层构建的,在构建的t层时,我们可以 ...

  8. POJ2104 k-th number 划分树

    又是不带修改的区间第k大,这次用的是一个不同的方法,划分树,划分树感觉上是模拟了快速排序的过程,依照pivot不断地往下划分,然后每一层多存一个toleft[i]数组,就可以知道在这一层里从0到i里有 ...

  9. 划分树 poj2104 hdu5249

    KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

随机推荐

  1. guava 学习笔记 使用瓜娃(guava)的选择和预判断使代码变得简洁

    guava 学习笔记 使用瓜娃(guava)的选择和预判断使代码变得简洁 1,本文翻译自 http://eclipsesource.com/blogs/2012/06/06/cleaner-code- ...

  2. tyvj1098[luogu 2365]任务安排 batch

    题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti.在每批任务开始 ...

  3. 在Android中如何获取视频的第一帧图片并显示在一个ImageView中

    String path  = Environment.getExternalStorageDirectory().getPath(); MediaMetadataRetriever media = n ...

  4. SpringMVC的Ajax提交

    这种类型的提交, 必须配合 multipartResolver, $("button:submit").click(function(){ $.ajax({ type : 'POS ...

  5. X200s,Debian 8(Jessie) 安装流水帐

    1. U盘启动安装 a. 因为无线网卡驱动是non-free,需要另外下载,对应X200s,文件是iwlwifi-5000-5.ucode,下完放到安装U盘的根目录下,安装时就不会再提示而是直接安装  ...

  6. Apache Rewrite 拟静态配置

    1.mod_rewrite 简介和配置 Rewirte主要的功能就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则表达式规范.平时帮助我们实现拟静态,拟目录,域名跳转,防止盗链等 2.mod_ ...

  7. QT QToolBox类

    QToolBox类的创建 //drawer.h #ifndef DRAWER_H #define DRAWER_H #include <QToolBox> #include <QTo ...

  8. spring 3.2.x + struts2 + mybatis 3.x + logback 整合配置

    与前面的一篇mybatis 3.2.7 与 spring mvc 3.x.logback整合 相比,只是web层的MVC前端框架,从spring mvc转换成struts 2.x系列,变化并不大 一. ...

  9. 基于SignalR的小型IM系统

    这个IM系统真是太轻量级了,提供的功能如下: 1.聊天内容美化 2.用户上下线提示 3.心跳包检测机制 4.加入用户可群聊 下面来一步一步的讲解具体的制作方法. 开篇准备工作 首先,巧妇难为无米之炊, ...

  10. 安卓开发:效果图中标注的像素尺寸如何转换为安卓的dp尺寸?

    我们的UI基于1920x1080分辨率给的尺寸标注,但是在安卓开发中大家一般都使用dp.sp来标注界面尺寸,所以需要一个dp与sp的转换公式. 一开始参考的的这篇文章:关于Android开发中px.d ...