Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 57543   Accepted: 19893
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.
题目链接:http://poj.org/problem?id=2104
题意:找出区间第k小。
思路:
如果x是区间第k个数,那么一定有在区间中有不超过x的数不少于k个。
因此如果可以快速求出区间里不超过x的数的个数,就可以通过对所有数进行二分搜索得到的x来求出第k个数。
接下来,如何计算在某个区间里不超过x个数的个数。如果不进行预处理,只能便利一遍所有的元素。
另一方面,如果区间是有序的,那么就可以通过二分搜索高效的求出不超过x的数的个数了。但是,如果对于每个查询都分别做一次排序,就完全无法降低复杂度。
所以考虑使用分块和线段树进行求解。
线段树每个节点都保存了对应区间排序之后的结果。建立线段树的过程和归并排序类似,而每个节点的数列就是其两个儿子节点的数列合并后的结果。建树的复杂度是O(nlogn)。这棵线段树就是归并排序的完整再现,叫做归并树。
要计算某个区间中不超过x的个数,只需要递归的进行操作,直至所给定的区间完全包含当前节点区间,然后二分搜索该节点上保存的数列。
因此可以在O(long2n)时间里求出不超过x的数的个数。所以整个算法的复杂度是O(nlogn+mlong3n)。
(PS:我的线段树处理不是归并排序的完整再现,而是首先对根节点中的数列排序,然后判断每个点是在当前节点的左儿子区间,还是在右儿子区间,然后依次保存到儿子的数列中,因为父亲是有序的,所以儿子也是有序的。)
代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<set>
using namespace std;
#define PI acos(-1.0)
typedef long long ll;
typedef pair<int,int> P;
const int maxn=5e5+,maxm=1e5+,inf=0x3f3f3f3f,mod=1e9+;
const ll INF=1e13+;
inline int get_int()
{
int num=;
char ch;
while((ch=getchar())!=' '&&ch!='\n')
num=num*+(ch-'');
return num;
}
/****************************/
struct edge
{
int from,to;
int cost;
};
edge es[maxm];
struct node
{
int num;
int k;
};
node sign[maxn];
int a[maxn];
int cmp(node x,node y)
{
return x.num<y.num;
}
vector<node>tree[maxn];
void build(int l,int r,int pos)
{
if(l==r) return;
int mid=(l+r)/;
for(int i=; i<tree[pos].size(); i++)
{
int k=tree[pos][i].k;
if(l<=k&&k<=mid) tree[pos<<].push_back(tree[pos][i]);
else tree[pos<<|].push_back(tree[pos][i]);
}
build(l,mid,pos<<);
build(mid+,r,pos<<|);
}
int query(int L,int R,int w,int l,int r,int pos)
{
///cout<<l<<" "<<r<<endl;
if(L<=l&&r<=R)
{
int s=,e=tree[pos].size()-;
int cou=-;
while(s<=e)
{
int md=(s+e)/;
if(tree[pos][md].num<=w) s=md+,cou=md;
else e=md-;
}
///cout<<cou+1<<endl;
return cou+1;
}
int mid=(l+r)/;
int ans=;
if(L<=mid) ans+=query(L,R,w,l,mid,pos<<);
if(R>mid) ans+=query(L,R,w,mid+,r,pos<<|);
return ans;
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=; i<n; i++)
{
scanf("%d",&a[i]);
sign[i].num=a[i],sign[i].k=i+;
}
sort(sign,sign+n,cmp);
for(int i=; i<n; i++) tree[].push_back(sign[i]);
build(,n,);
while(q--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
int L=,R=n-;
int ans=-;
while(L<=R)
{
int mid=(L+R)/;
int w=sign[mid].num;
///cout<<"x="<<w<<endl;
if((query(l,r,w,1,n,1))>=k) R=mid-1,ans=mid;
else L=mid+;
}
cout<<sign[ans].num<<endl;
}
return ;
}

归并树

POJ 2014.K-th Number 区间第k小 (归并树)的更多相关文章

  1. POJ 2104 K-th Number(区间第k大数)(平方切割,归并树,划分树)

    题目链接: http://poj.org/problem? id=2104 解题思路: 由于查询的个数m非常大.朴素的求法无法在规定时间内求解. 因此应该选用合理的方式维护数据来做到高效地查询. 假设 ...

  2. 【POJ】【2104】区间第K大

    可持久化线段树 可持久化线段树是一种神奇的数据结构,它跟我们原来常用的线段树不同,它每次更新是不更改原来数据的,而是新开节点,维护它的历史版本,实现“可持久化”.(当然视情况也会有需要修改的时候) 可 ...

  3. HDU 2665.Kth number 区间第K小

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. POJ2104 K-th Number —— 区间第k小 整体二分

    题目链接:https://vjudge.net/problem/POJ-2104 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Tota ...

  5. BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 418   Solved: 235 [ Submit][ ...

  6. POJ-2104-K-th Number(区间第K大+主席树模板题)

    Description You are working for Macrohard company in data structures department. After failing your ...

  7. poj2104 K-th Number区间第k小值 主席树

    原来主席树就是可持久化线段树啊,刚知道,,, 作为一道裸题,还是必A的,然而一开始偷懒不写离散化跪了N多遍,后来在缪大的帮助下发现了这个问题,遂A之 ——又是这种破问题,实在不想说自己了 把n个数看成 ...

  8. POJ 2104 K-th Number 主席树(区间第k大)

    题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...

  9. 【POJ】2104 K-th Number(区间k大+主席树)

    http://poj.org/problem?id=2104 裸题不说.主席树水过. #include <cstdio> #include <iostream> #includ ...

随机推荐

  1. JS-事件对象(鼠标键盘事件)

    一  事件对象 1 需要获取键盘和鼠标的信息的时候,用到事件对象.(e) 例如:document.onclick = function(e){ var  e = e || event;(做兼容) } ...

  2. Maximum Likelihood及Maximum Likelihood Estimation

    1.What is Maximum Likelihood? 极大似然是一种找到最可能解释一组观测数据的函数的方法. Maximum Likelihood is a way to find the mo ...

  3. python 函数的动态参数 命名空间,作用域以及函数嵌套,global和nonlocal (重点)

    *** 坚持坚持,即使你不太强*** 1.函数的动态传参 2.函数的命名空间及作用域 3.函数嵌套 4.global和nonlocal关键字 一.函数的动态传参 1. *args: 位置参数动态传参, ...

  4. 关于Windows下无法在MySQL安装目录找到配置文件my.ini

    目前5.7版本的MySQL的配置文件my.ini位于: C:\ProgramData\MySQL\MySQL Server 5.7

  5. zabbix3.0.4安装部署与SendEmail报警配置

    MySQL:5.6.21 nginx:1.62 PHP:5.7 pcre:8.32 zabbix:3.0.4 LNMP安装步骤略过 # tar xvf zabbix-3.0.4.tar.gz # cd ...

  6. js实现右击

    <!DOCTYPE html> <html>     <head>  <meta charset="UTF-8">  <tit ...

  7. nagios维护之常见问题

    一.重启nagios 报错: Starting nagios:This account is currently not available.     #这个账户目前不可用: 解决方法: a.编辑/e ...

  8. Django、Flask、Tornado的比较

    一:常用请求参数的接收 Django中: request.GET/POST Tornado中: self.get_query_argument()/get_query_arguments() self ...

  9. 互联网进行限流策略的Semaphore信号量使用

    在Semaphore信号量非常适合高并发访问,新系统在上线之前,要对系统的访问量进行评估,当然这个值肯定不是随便拍拍脑袋就能想出来的,是经过以往的经验.数据.历年的访问量,已经推广力度进行一个合理的评 ...

  10. 大数据分析界的“神兽”Apache Kylin有多牛?【转】

    本文作者:李栋,来自Kyligence公司,也是Apache Kylin Committer & PMC member,在加入Kyligence之前曾就职于eBay.微软. 1.Apache ...