动态开点主席树板子

#include<bits/stdc++.h>
#define getsize(p) (p?p->sz:0)
using namespace std;
typedef long long ll;
const int N=2e5+10;
struct node{
    int l,r;
    int sz;
    node *ls,*rs;
}pool[N*40];
node *rt[N];
int idx;
vector<int> num;
int a[N];
node * copynode(node *rt){
    node *p=pool+(++idx);
    pool[idx]=*rt;
    return p;
}
node * newnode(int l,int r){
    node *p=pool+(++idx);
    p->l=l,p->r=r;
    return p;
}
node *insert(node *rt,int l,int r,int x){
    node *p;
    if(rt) p=copynode(rt);
    else p=newnode(l,r);
    p->sz++;
    int mid=l+r>>1;
    if(p->l==x&&p->r==x){
        return p;
    }
    if(x<=mid)
        p->ls=insert(p->ls,l,mid,x);
    else
        p->rs=insert(p->rs,mid+1,r,x);

    return p;
}
int query(node *pl,node *pr,int k){
    if(pr->l==pr->r)
        return pr->l;
    int n;
    if(!pl){
        n=getsize(pr->ls);
        if(n>=k)
            return query(0,pr->ls,k);
        else
            return query(0,pr->rs,k-n);
    }
    else{
        n=getsize(pr->ls)-getsize(pl->ls);
        if(n>=k)
            return query(pl->ls,pr->ls,k);
        else
            return query(pl->rs,pr->rs,k-n);
    }
}
int main(){
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    int i;
    for(i=1;i<=n;i++){
        cin>>a[i];
        num.push_back(a[i]);
    }
    sort(num.begin(),num.end());
    num.erase(unique(num.begin(),num.end()),num.end());
    for(i=1;i<=n;i++){
        int x=lower_bound(num.begin(),num.end(),a[i])-num.begin()+1;
        rt[i]=insert(rt[i-1],1,n,x);
    }
    int l,r,k;
    while(m--){
        cin>>l>>r>>k;
        cout<<num[query(rt[l-1],rt[r],k)-1]<<endl;
    }
}
View Code

 

posted @ 2020-08-03 10:53  朝暮不思  阅读(119)  评论(0编辑  收藏  举报