題目鏈接:POJ 2104
Time Limit: 20000MS | Memory Limit: 65536K | |
Total Submissions: 59422 | Accepted: 20698 | |
Case Time Limit: 2000MS |
Description
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 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
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
//
// main.cpp
// POJ 2104 K-th Number
//
// Created by teddywang on 2017/09/07.
// Copyright © 2017年 teddywang. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Node{
int a,b,rs,ls,sum;
}tr[2000010];
int a[100010];
int rt[100010],pos,cnt;
struct node{
int id;
int num;
friend bool operator < (node a,node b)
{
return a.num<b.num;
}
}b[100010];
int ranks[100010];
void Build(int &node,int l,int r)
{
node=++cnt;
tr[node].a=l;
tr[node].b=r;
if(l==r)return;
int mid=(l+r)>>1;
Build(tr[node].ls,l,mid);
Build(tr[node].rs,mid+1,r);
}
void Insert(int pre,int &node)
{
node=++cnt;
tr[node].ls=tr[pre].ls;
tr[node].rs=tr[pre].rs;
tr[node].a=tr[pre].a;
tr[node].b=tr[pre].b;
tr[node].sum=tr[pre].sum+1;
if(tr[node].a==tr[node].b)return;
int mid=(tr[node].a+tr[node].b)>>1;
if(mid>=pos)Insert(tr[pre].ls,tr[node].ls);
else Insert(tr[pre].rs,tr[node].rs);
}
int Query(int pre,int node,int k)
{
if(tr[node].ls==tr[node].rs)return b[tr[node].a].num;
int cmp=tr[tr[node].ls].sum-tr[tr[pre].ls].sum;
if(cmp>=k)return Query(tr[pre].ls,tr[node].ls,k);
else return Query(tr[pre].rs,tr[node].rs,k-cmp);
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;b[i].num=a[i],i++)
{
scanf("%d",&a[i]);
b[i].id=i;
}
sort(b+1,b+n+1);
for(int i=1;i<=n;i++)
{
ranks[b[i].id]=i;
}
Build(rt[0],1,n);
for(int i=1;i<=n;i++)
{
pos=ranks[i];
Insert(rt[i-1],rt[i]);
}
int l,r,k;
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",Query(rt[l-1],rt[r],k));
}
return 0;
}