[POJ2104] K-th Number(区间K小数,主席树模板)

Description

N 个数,M个询问区间 k <script type="math/tex" id="MathJax-Element-42">k</script>小值

Solution

显然可以用主席树维护,不解释。

注意要离散化

啊?主席树是什么?看这里

Code

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
#define MAXN 100005
using namespace std;
struct node
{
    int ls,rs,sm;
}tr[20*MAXN];
struct number
{
    int x,y;
}b[MAXN];
bool cmp(number x,number y)
{
    return x.x<y.x;
}
int rt[MAXN],a[MAXN],n,m,num,nd,pt[MAXN];
void build(int lst,int now,int l,int r,int v)
{
    if (l==r) 
    {
        tr[now].sm=tr[lst].sm+1;
        return;
    }
    int mid=(l+r)/2;
    if (v<=mid) 
    {
        tr[now].rs=tr[lst].rs;
        tr[now].ls=++nd;
        build(tr[lst].ls,nd,l,mid,v);
    }
    else 
    {
        tr[now].ls=tr[lst].ls;
        tr[now].rs=++nd;
        build(tr[lst].rs,nd,mid+1,r,v);
    } 
    tr[now].sm=tr[tr[now].ls].sm+tr[tr[now].rs].sm;
}
int find(int lst,int now,int l,int r,int v)
{
    if (l==r) return l;
    int mid=(l+r)/2;
    int ls1=tr[lst].ls,ls2=tr[now].ls,sum=tr[ls2].sm-tr[ls1].sm;
    if (sum<v) return find(tr[lst].rs,tr[now].rs,mid+1,r,v-sum);
    else return find(tr[lst].ls,tr[now].ls,l,mid,v);
}
int main()
{
    cin>>n>>m;
    int i,j;
    num=0,nd=0;
    fo(i,1,n) 
    {
        scanf("%d",&a[i]);
        b[i].x=a[i];
        b[i].y=i;
    }
    sort(b+1,b+n+1,cmp);
    fo(i,1,n) 
    {
        if (b[i].x!=b[i-1].x) num++;
        pt[num]=b[i].x;
        a[b[i].y]=num; 
    }
    fo(i,1,n)
    {
        rt[i]=++nd;
        build(rt[i-1],rt[i],1,n,a[i]);
    }
    fo(i,1,m)
    {
        int x,y,k;
        scanf("%d%d%d",&x,&y,&k);
        printf("%d\n",pt[find(rt[x-1],rt[y],1,n,k)]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值