HDU 2665 Kth number 主席树模板题

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2665

主席树模板题

代码 :

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define sf scanf
#define pf printf
#define totNode maxn * 60
using namespace std;
const int maxn = 100000 + 50;
int ch[totNode][2],SUM[totNode],tot;
void Insert(int prt,int rt,int l,int r,int x,int v){
    SUM[rt] = SUM[prt] + v;
    while(l < r){
        int mid = l + r >> 1;
        if(x <= mid){
            ch[rt][0] = tot++;
            ch[rt][1] = ch[prt][1];
            rt = ch[rt][0],prt = ch[prt][0];
            r = mid;
        }
        else{
            ch[rt][1] = tot++;
            ch[rt][0] = ch[prt][0];
            rt = ch[rt][1],prt = ch[prt][1];
            l = mid + 1;
        }
        SUM[rt] = SUM[prt] + v;
    }
}
int Query(int rt1,int rt2,int l,int r,int k){
    while(l < r){
        int mid = l + r >> 1;
        if( (SUM[ch[rt2][0]] - SUM[ch[rt1][0]]) >= k){
            r = mid;
            rt1 = ch[rt1][0],rt2 = ch[rt2][0];
        }
        else{
            k = k - (SUM[ch[rt2][0]] - SUM[ch[rt1][0]]);
            l = mid + 1;
            rt1 = ch[rt1][1],rt2 = ch[rt2][1];
        }
    }
    return l;
}
int rts[maxn];
struct Node{
    int v,id;
}Nodes[maxn];
bool cmp(const Node& a,const Node& b){
    return a.v < b.v;
}
int pos[maxn];
int main(){
    int n,m;
    int T;sf("%d",&T);
    while(T--){
        sf("%d %d",&n,&m);
        tot = 1;
        SUM[0] = 0;ch[0][0] = ch[0][1] = 0;
        for(int i = 1;i <= n;++i){
            sf("%d",&Nodes[i].v);Nodes[i].id = i;
        }
        sort(Nodes + 1,Nodes + 1 + n,cmp);
        for(int i = 1;i <= n;++i){
            pos[Nodes[i].id] = i;
        }
        for(int i = 1;i <= n;++i) Insert(rts[i - 1],rts[i] = tot++,1,n,pos[i],1);
        while(m--){
            int x,y,k;sf("%d %d %d",&x,&y,&k);
            pf("%d\n",Nodes[Query(rts[x - 1],rts[y],1,n,k)].v);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值