K-th Number
Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 59798   Accepted: 20879
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

题意:给出一列数组和几组查询,对于每个查询(i,j,k),要求输出a(i)~a(j)的升序排列的第k大数。

思路:挑战者上的题目,上面采用的是平方分割法,总体来讲,线段树的复杂度肯定是比平方分割的复杂度更小,但平方分割的实现更加简单易懂。

但是敲了一遍书上的代码,不知道是不是手残,敲完以后总有个别数据对不上答案(心累,调了一个小时不知所以然)。

给出AC代码

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std; #define MAXN 100010
#define MAXM 5010
#define B 1000 //桶的大小 //输入
int n,m;
int a[MAXN];
int L[MAXM],R[MAXM],K[MAXM]; int num[MAXN]; //对A排序后的结果
vector<int> bucket[MAXN/B]; //每个桶排序后的结果 void solve()
{
for(int i=0;i<n;i++)
{
bucket[i/B].push_back(a[i]);
num[i]=a[i];
}
sort(num,num+n);
for(int i=0;i<n/B;i++)
sort(bucket[i].begin(),bucket[i].end());
for(int i=0;i<m;i++)
{
//求[L,R]区间的第K个数
int l=L[i]-1,r=R[i],k=K[i];
int left=-1,right=n-1,mid;
while(right-left>1)
{
mid=(left+right)/2;
int x=num[mid];
int tl=l,tr=r,c=0; //区间两端多出的部分
while(tl<tr&&tl%B!=0){
if(a[tl++]<=x) c++;
}
while(tl<tr&&tr%B!=0){
if(a[--tr]<=x) c++;
} //对每个桶进行计算
while(tl<tr)
{
int b=tl/B;
c+=upper_bound(bucket[b].begin(),bucket[b].end(),x)-bucket[b].begin();
tl+=B;
} if(c>=k)
right=mid;
else
left=mid;
}
printf("%d\n",num[right]);
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<m;i++)
scanf("%d%d%d",&L[i],&R[i],&K[i]);
solve();
return 0;
}

平方分割poj2104K-th Number的更多相关文章

  1. POJ2104 K-th Number 静态区间第k最值 平方分割

    干掉这道题的那一刻,我只想说:我终于**的AC了!!! 最终内存1344K,耗时10282ms,比起归并树.划分树以及其他各种黑科技,这个成绩并不算光彩⊙﹏⊙ 但至少,从最初的无数次TLE到最终的AC ...

  2. ZOJ2112 Dynamic Rankings 动态区间第K最值 平方分割

    有了上一题的经验(POJ的静态区间第K最值)再解决这道题就轻松多了 空间5256KB,时间3330ms,如果把动态开点的平衡树换成数组模拟的话应该会更快 之所以选择了平方分割而不是树套树,不仅是所谓趁 ...

  3. POJ2104 (平方分割)二分查找理解。

    题意:任意区间求第k大数 思路: 预处理:利用平方分割(分桶法)把区间切割成B = sqrt(n)大小的一块块,然后每个各自排序. 二分第k大数x,接着就需要求[l,r]区间中x的排名,与k比较,将两 ...

  4. 静态区间第k大(分桶法和平方分割)

    POJ 2104为例 思想: <挑战程序设计竞赛>中介绍的方法. 分桶法:把一排物品或者平面分成桶,每个桶分别维护自己内部的信息,已达到高效计算的目的. 设一共有n个数,每b个分到一个桶里 ...

  5. Big String 块状数组(或者说平方分割)

    Big String 给一个字符串,长度不超过 106,有两种操作: 1. 在第 i 个字符的前面添加一个字符 ch 2. 查询第 k 个位置是什么字符 操作的总数不超过 2000 如果直接模拟的话, ...

  6. POj 2104 K-th Number (分桶法+线段树)

    题目链接 Description You are working for Macrohard company in data structures department. After failing ...

  7. POJ2104 K-th Number(归并树)

    平方分割一直TLE,最后用归并树处理过了,使用STL会比较慢. #include<cstdio> #include<iostream> #include<cstdlib& ...

  8. BZOJ 2440 中山市选2011 全然平方数 二分答案+容斥原理+莫比乌斯反演

    题目大意:求第k个无平方因子数是多少(无视原题干.1也是全然平方数那岂不是一个数也送不出去了? 无平方因子数(square-free number),即质因数分解之后全部质因数的次数都为1的数 首先二 ...

  9. POJ 2104 K-th Number ( 求取区间 K 大值 || 主席树 || 离线线段树)

    题意 : 给出一个含有 N 个数的序列,然后有 M 次问询,每次问询包含 ( L, R, K ) 要求你给出 L 到 R 这个区间的第 K 大是几 分析 : 求取区间 K 大值是个经典的问题,可以使用 ...

随机推荐

  1. codeforces 362A找规律

    刚开始以为是搜索白忙活了原来是个简单的找规律,以后要多想啊 此题是两马同时跳 A. Two Semiknights Meet time limit per test 1 second memory l ...

  2. POJ 2778 (AC自动机+矩阵乘法)

    POJ 2778 DNA Sequence Problem : 给m个只含有(A,G,C,T)的模式串(m <= 10, len <=10), 询问所有长度为n的只含有(A,G,C,T)的 ...

  3. Linux下汇编语言学习笔记26 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  4. poj_3006_Dirichlet's Theorem on Arithmetic Progressions_201407041030

    Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  5. Spring集成Jedis(不依赖spring-data-redis)(单机/集群模式)(待实践)

    Jedis是Redis的Java客户端,Spring将Jedis连接池作为一个Bean来配置.如果在Spring Data的官网上可以发现,Spring Data Redis已经将Jedis集成进去了 ...

  6. JS中的apply、call、bind区别

    apply.call.bind 用法 1:作用 改变函数运行时的上下文,即改变this的指向问题. xxxFunction.call(this,arg1,arg2,arg3); xxxFunction ...

  7. JAVA 小程序之ATM

    一个JAVA的小程序,主要要求有模块化编程的思想,能够把ATM中各个功能独立成为一个一个的方法. ATM主要功能有: 查询余额: 取款: 存款: 修改密码: 退出. 以上功能均由独立的方法给出,具体实 ...

  8. Vmware worksiation中使用ISO

    Vmware技巧: 用ISO安装系统,需要添加2个CD设备. IDE 1  中选择 autoinst.iso IDE 2  中选择 “要安装的系统”.iso 简单讲:Vmware模拟机上需要模拟两次i ...

  9. poj1151==codevs 3044 矩形面积求并

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21511   Accepted: 8110 Descrip ...

  10. 利用游标返回结果集的的例子(Oracle 存储过程)JAVA调用方法和.NET调用方法

    在sqlplus中建立如下的内容: 1.程序包 SQL> create or replace package types  2  as  3      type cursorType is re ...