主席树 模板

#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define M 2000010
int root[N],R[M],L[M],s[M],m,x,y,n,k,a[N],cnt;

void update(int &A,int &B,int l,int r,int k){
    B=++cnt;
    s[B]=s[A]+1;
    if(l==r)return;
    int mid=(l+r)/2;
    if(k<=mid)update(L[A],L[B],l,mid,k);
    else update(R[A],R[B],mid+1,r,k);
    if(!L[B])L[B]=L[A];
    if(!R[B])R[B]=R[A];
}

int find(int A,int B,int l,int r){
    if(l==r)return l;
    int mid=(l+r)/2;
    if(s[R[B]]-s[R[A]]>=k)return find(R[A],R[B],mid+1,r);
    else{
        k-=s[R[B]]-s[R[A]];
        return find(L[A],L[B],l,mid);
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)update(root[i-1],root[i],1,100000,a[i]);
    while(m--){
        scanf("%d%d%d",&x,&y,&k);
        cout<<find(root[x-1],root[y],1,100000)<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/codetogether/p/7191486.html