码迷,mamicode.com
首页 > 其他好文 > 详细

【Poj2761】Feed the dogs(主席树)

时间:2018-02-04 17:59:02      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:efi   read   --   space   sci   names   blog   har   get   

Desciption

题意:求区间第K小(N<=100000)

Solution

主席树模板题

Code

#include <cstdio>
#include <algorithm>
#define N 100010
using namespace std;

int n,m,A[N],rank[N],T[N],ls[N*20],rs[N*20],sum[N*20],tot;

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

void update(int last,int p,int l,int r,int &rt){
    rt=++tot;
    ls[rt]=ls[last],rs[rt]=rs[last],sum[rt]=sum[last]+1;
    if(l==r) return;
    int m=(l+r)>>1;
    if(p<=m) update(ls[last],p,l,m,ls[rt]);
    else update(rs[last],p,m+1,r,rs[rt]);
}

int Query(int ss,int tt,int l,int r,int k){
    if(l==r) return l;
    int m=(l+r)>>1;
    int d=sum[ls[tt]]-sum[ls[ss]];
    if(k<=d) return Query(ls[ss],ls[tt],l,m,k);
    else return Query(rs[ss],rs[tt],m+1,r,k-d);
}

int main(){
    n=read(),m=read();
    for(int i=1;i<=n;++i) A[i]=rank[i]=read();
    sort(rank+1,rank+n+1);
    int cnt=unique(rank+1,rank+n+1)-(rank+1);
    for(int i=1;i<=n;++i) A[i]=lower_bound(rank+1,rank+cnt+1,A[i])-rank;
    for(int i=1;i<=n;++i) update(T[i-1],A[i],1,cnt,T[i]);
    while(m--){
        int l=read(),r=read(),k=read();
        printf("%d\n",rank[Query(T[l-1],T[r],1,cnt,k)]);
    }
    return 0;
}

【Poj2761】Feed the dogs(主席树)

标签:efi   read   --   space   sci   names   blog   har   get   

原文地址:https://www.cnblogs.com/void-f/p/8413425.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!