主席树(权值线段树)模板
可持久化线段树2
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=1e6+5;
struct ren{
int l,r,sum;
}t[MAXN<<5];
int n,m,cnt,rt[MAXN],a[MAXN],b[MAXN];
int build(int p,int l,int r){
p=++cnt;
if(l==r){return p;}
int mid=(l+r)>>1;
t[p].l=build(t[p].l,l,mid);t[p].r=build(t[p].r,mid+1,r);
return p;
}
int update(int pre,int l,int r,int x){
int p=++cnt;
t[p].l=t[pre].l;t[p].r=t[pre].r;t[p].sum=t[pre].sum+1;
if(l==r) return p;
int mid=(l+r)>>1;
if(x<=mid) t[p].l=update(t[pre].l,l,mid,x);
else t[p].r=update(t[pre].r,mid+1,r,x);
return p;
}
int query(int pre,int p,int l,int r,int k){
if(l==r) return l;
int x=t[t[p].l].sum-t[t[pre].l].sum;
int mid=(l+r)>>1;
if(x>=k) return query(t[pre].l,t[p].l,l,mid,k);
else return query(t[pre].r,t[p].r,mid+1,r,k-x);
}
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+1+n);
int c1=unique(b+1,b+1+n)-b-1;
rt[0]=build(0,1,c1);
for(int i=1;i<=n;i++){a[i]=lower_bound(b+1,b+1+c1,a[i])-b,rt[i]=update(rt[i-1],1,c1,a[i]);}
for(int i=1;i<=m;i++){
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",b[query(rt[l-1],rt[r],1,c1,x)]);
}
return 0;
}
本文来自博客园,作者:{StranGePants},转载请注明原文链接:https://www.cnblogs.com/StranGePants/p/15923886.html