您的位置:首页 > 其它

POJ 2104 K-th Number

2016-10-12 15:01 211 查看
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.

【题目分析】

可持久化线段树

【代码】

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int root[100001*40],ls[100001*40],rs[100001*40];
int a[100001],b[100001],n,q,top,node;
int size[100001*40];
inline int insert(int o,int l,int r,int k)
{
int now=++node;
size[now]=size[o]+1;
if (l==r) return now;
int mid=(l+r)/2;
if (k<=mid) ls[now]=insert(ls[o],l,mid,k),rs[now]=rs[o];
else rs[now]=insert(rs[o],mid+1,r,k),ls[now]=ls[o];
return now;
}
inline int ask(int o1,int o2,int l,int r,int k)
{
if (l==r) return l;
int mid=(l+r)/2;
if (k<=size[ls[o2]]-size[ls[o1]]) return ask(ls[o1],ls[o2],l,mid,k);
else return ask(rs[o1],rs[o2],mid+1,r,k-size[ls[o2]]+size[ls[o1]]);
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for (int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
top=unique(b+1,b+n+1)-b-1;
for (int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+top+1,a[i])-b;
for (int i=1;i<=n;++i) root[i]=insert(root[i-1],1,top,a[i]);
while (q--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",b[ask(root[l-1],root[r],1,top,k)]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj