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

poj 2104 K-th Number (主席树)

时间:2015-07-28 23:20:12      阅读:399      评论:0      收藏:0      [点我收藏+]

标签:

/*
求l,r这个死序列中第k小的数
*/
#include <stdio.h>
#include <algorithm>
# include <string.h>
using namespace std;
# define lson l,m
# define rson m+1,r
# define N 100005
int a[N],Hash[N];
int T[N];///树祖宗节点的编号
int sum[N<<5];//数目
int L[N<<5];//左儿子的编号
int R[N<<5];//右儿子的编号
int tot;
int build(int l,int r)
{
    int rt=(++tot);
    sum[rt]=0;
    if(l<r)
    {
        int m=(l+r)>>1;
        L[rt]=build(lson);
        R[rt]=build(rson);
    }
    return rt;
}
int update(int pre,int l,int r,int x)
{
    int rt=(++tot);
    L[rt]=L[pre];
    R[rt]=R[pre];
    sum[rt]=sum[pre]+1;
    if(l<r)
    {
        int m=(l+r)>>1;
        if(x<=m)
            L[rt]=update(L[pre],lson,x);
        else
            R[rt]=update(R[pre],rson,x);
    }
    return rt;
}
int query(int u,int v,int l,int r,int k)
{
    if(l>=r)
        return l;
    int m=(l+r)>>1;
    int num=sum[L[v]]-sum[L[u]];
    if(num>=k)
        return query(L[u],L[v],lson,k);
    else
        return query(R[u],R[v],rson,k-num);
}
int main()
{
    int n,m,i;
    while(~scanf("%d%d",&n,&m))
    {
        tot=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            Hash[i]=a[i];
        }
        sort(Hash+1,Hash+n+1);//离散
        int size=unique(Hash+1,Hash+n+1)-Hash-1;
        T[0]=build(1,size);//裸树
        for(i=1;i<=n;i++)//在T[0]的基础上建n棵树
        {
            int x=lower_bound(Hash+1,Hash+size+1,a[i])-Hash;
            T[i]=update(T[i-1],1,size,x);
        }
        while(m--)
        {
            int l,r,k;
            scanf("%d%d%d",&l,&r,&k);
            int x=query(T[l-1],T[r],1,size,k);
            printf("%d\n",Hash[x]);
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

poj 2104 K-th Number (主席树)

标签:

原文地址:http://blog.csdn.net/lp_opai/article/details/47111197

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