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. iOS ARC内存管理

    iOS的内存管理机制,只要是iOS开发者,不管多长的时间经验,都能说出来一点,但是要深入的理解.还是不简单的.随着ARC(自动管理内存)的流行.iOS开发者告别了手动管理内存的复杂工作.但是自动管理内 ...

  2. linux系统下对网站实施负载均衡+高可用集群需要考虑的几点

    随着linux系统的成熟和广泛普及,linux运维技术越来越受到企业的关注和追捧.在一些中小企业,尤其是牵涉到电子商务和电子广告类的网站,通常会要求作负载均衡和高可用的Linux集群方案. 那么如何实 ...

  3. Java集合系列:-----------04fail-fast总结(通过ArrayList来说明fail-fast的原理以及解决办法)

    前面,我们已经学习了ArrayList.接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解.内容包括::1 fail-fast简介2 fail-fast示例3 f ...

  4. usb驱动开发16之设备生命线

    回到struct usb_hcd,继续努力的往下看. kref,usb主机控制器的引用计数.struct usb_hcd也有自己专用的引用计数函数,看hcd.c文件. static void hcd_ ...

  5. MongoDB JAVA API Filters

    Filters 该过滤器类为所有的MongoDB的查询操作静态工厂方法.每个方法返回BSON类型,又可以传递给期望一个查询过滤器的任何方法的一个实例. eq:匹配等于指定值的值.gt:匹配大于指定值的 ...

  6. 条件变量pthread_cond_t怎么用

    #include <pthread.h> #include <stdio.h> #include <stdlib.h> pthread_mutex_t mutex ...

  7. jboss CLI 命令行接口学习(适用JBOSS EAP 6.2+)

    一.确认CLI所使用的端口 以domain模式为例,查看domain controller(也就是master主机)上的host.xml <management-interfaces> & ...

  8. 关于viewpager 里嵌套 listview 同时实现翻页功能的“java.lang.IllegalStateException: The specified child..."异常处理

    这几天做项目用到了ViewPager,因为它可以实现左右划动多个页面的效果,然后 再每个页面里使用ListView,运行时总是出现”PagerAdapter java.lang.IllegalStat ...

  9. TensorFlow 源代码初读感受

    把自己微博发的文章:http://www.weibo.com/1804230372/En7PdlgLb?from=page_1005051804230372_profile&wvr=6& ...

  10. WPF 让子元素动起来!

    在没有接触Blend之前,自己整出了一个MultiTouchHelper,这东西是做什么的呢?就是利用附加属性让元素可以多点触控. 然后某一天发现Blend里面有一个Behavior的东西,我去,原来 ...