POJ–2104 K-th Number

主席树。

主席树复习,这道题是主席树的经典入门了吧。。

无修改区间第k大。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 200000 + 10;
const int maxm = 5000000 + 10;

/*
void build(int &x,int L,int R) {
    if(!x) x=++vid;
    if(L==R) return;
    int mid = (L+R)>>1;
    build(lc[x],L,mid);
    build(rc[x],mid+1,R);
}*/

int root[maxn];
int lc[maxm],rc[maxm],s[maxm],vid;
int n,m,q,cur;
int a[maxn],t[maxn];

void modify(int &x,int y,int L,int R,int pos,int val=1) {
    x=++vid; s[x]=s[y]+val;
    lc[x]=lc[y]; rc[x]=rc[y];    
    if(L==R) return;
    int mid = (L+R)>>1;
    if(pos<=mid) modify(lc[x],lc[y],L,mid,pos);
    else modify(rc[x],rc[y],mid+1,R,pos);
}

int query(int x,int y,int k) {
    int l=1,r=m;
    while(l<r) {
        cur=s[lc[x]]-s[lc[y]];
        int mid=(l+r)>>1;
        if(k<=cur) {
            x=lc[x]; y=lc[y]; r=mid;     
        }
        else {
            x=rc[x]; y=rc[y]; l=mid+1; k-=cur;
        }
    }
    return l;
}

int l,r,k;

int main() {
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        t[i]=a[i];
    }
    //printf("test\n");
    sort(t+1,t+n+1);
    m=unique(t+1,t+n+1)-(t+1);
    for(int i=1;i<=n;i++) a[i]=lower_bound(t+1,t+m+1,a[i])-t;
    for(int i=1;i<=n;i++) modify(root[i],root[i-1],1,m,a[i]);
    while(q--) {
        scanf("%d%d%d",&l,&r,&k);
        printf("%d\n",t[query(root[r],root[l-1],k)]);
    }
    return 0;
}
posted @ 2016-07-20 21:37  invoid  阅读(216)  评论(0编辑  收藏  举报