P3834 【模板】可持久化线段树 2(主席树)

P3834 【模板】可持久化线段树 2(主席树)

静态查询区间第k小

离散化挂了.....

注意$|a_i|<=10^9$,所以离散化的时候$b[0]=-2e9$以防止$0$被忽略录入

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=200003;
int n,u,m,a[N],b[N],rt[N],lc[N*18],rc[N*18],s[N*18],U;
#define mid (l+r)/2
void Add(int &o,int e,int l,int r,int k){
    s[o=++U]=s[e]+1,lc[o]=lc[e],rc[o]=rc[e];
    if(l==r) return ;
    if(k<=mid) Add(lc[o],lc[e],l,mid,k);
    else Add(rc[o],rc[e],mid+1,r,k);
}
int Ask(int o,int e,int l,int r,int k){
    if(l==r) return l;
    int w=s[lc[o]]-s[lc[e]];
    if(k<=w) return Ask(lc[o],lc[e],l,mid,k);
    else return Ask(rc[o],rc[e],mid+1,r,k-w);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i];
    sort(b+1,b+n+1); b[0]=-2e9;
    for(int i=1;i<=n;++i) if(b[i]!=b[i-1]) b[++u]=b[i];
    for(int i=1;i<=n;++i)
        Add(rt[i],rt[i-1],1,u,lower_bound(b+1,b+u+1,a[i])-b);
    for(int i=1,L,R,k;i<=m;++i){
        scanf("%d%d%d",&L,&R,&k);
        printf("%d\n",b[Ask(rt[R],rt[L-1],1,u,k)]);
    }
    return 0;
}

 

posted @ 2021-07-24 22:09  kafuuchino  阅读(42)  评论(0编辑  收藏  举报