【静态区间K大-权值线段树】POJ 2104 K-th Number

通道

题意:区间K大

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,sz,tot;
int root[100001],a[100001],ls[8000001],rs[8000001],s[8000001];
int num[100001],hash[100001];
void insert(int l,int r,int x,int &y,int v){
    y=++sz;
    s[y]=s[x]+1;
    if(l==r)return;
    ls[y]=ls[x];rs[y]=rs[x];
    int mid=(l+r)>>1;
    if(v<=mid)insert(l,mid,ls[x],ls[y],v);
    else insert(mid+1,r,rs[x],rs[y],v);
}
int ask(int l,int r,int x,int y,int k){
    if(l==r)return l;
    int mid=(l+r)>>1;
    if(s[ls[y]]-s[ls[x]]>=k)
       return ask(l,mid,ls[x],ls[y],k);
    else return ask(mid+1,r,rs[x],rs[y],k-(s[ls[y]]-s[ls[x]]));
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
       scanf("%d",&a[i]);
       num[i]=a[i];
    }
    sort(num+1,num+n+1);
    hash[++tot]=num[1];
    for(int i=2;i<=n;i++)
       if(num[i]!=num[i-1])
          hash[++tot]=num[i];
    for(int i=1;i<=n;i++)
        insert(1,tot,root[i-1],root[i],lower_bound(hash + 1, hash + 1 + tot, a[i]) - hash); 
    for(int i=1;i<=m;i++) {
        int l,r,x;scanf("%d%d%d",&l,&r,&x);
        printf("%d\n",hash[ask(1,tot,root[l-1],root[r],x)]);
    }
    return 0;
}
View Code

 

posted @ 2015-08-30 21:39  mithrilhan  阅读(343)  评论(0编辑  收藏  举报