主席树+动态开点

/*
    the k-th number
    主席树+动态开点
    by sbn
    2017-12-26 
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
struct node{
    int l,r;
    int sum;
    node():sum(0){l=r=0;};
}   JZM_tree[3000550];
int head[200051];
ll cnt,n,m,tot,arr[200051];
ll cnt_root;
inline int new_node(){
    tot++;
    JZM_tree[tot].sum=JZM_tree[tot].l=JZM_tree[tot].r=0;
    return tot;
}
inline void update(int &u,int v,ll l,ll r,ll pos){
    if (!v) u=new_node();
    else{
        u=++tot;
        JZM_tree[u]=JZM_tree[v];
    }
    JZM_tree[u].sum++;
    if (l==r-1) return;
    int mid=(l+r)>>1;
    if (pos<mid)    update(JZM_tree[u].l,JZM_tree[v].l,l,mid,pos);
    else update(JZM_tree[u].r,JZM_tree[v].r,mid,r,pos);
}
inline ll   get(int u,int v,ll l,ll r,ll rank){
    if (l==r-1) return l;
    int suml=JZM_tree[JZM_tree[u].l].sum-JZM_tree[JZM_tree[v].l].sum;
    int mid=(l+r)>>1;
    if (rank<=suml) return get(JZM_tree[u].l,JZM_tree[v].l,l,mid,rank);
    else return get(JZM_tree[u].r,JZM_tree[v].r,mid,r,rank-suml);
}
int main(){
    cin>>n>>m;
    memset(head,0,sizeof(head));
    tot=0;
    for (int i=1;i<=n;i++)  {
        cin>>arr[i];
        cnt_root++;
        update(head[cnt_root],head[cnt_root-1],-2e9,2e9,arr[i]);
    }

    for (int i=1;i<=m;i++){
        int x,y,z;
        cin>>x>>y>>z;
        cout<<get(head[y],head[x-1],-2e9,2e9,z)<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值