主席树(权值线段树)模板

可持久化线段树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;
}
posted @ 2022-02-22 16:49  StranGePants  阅读(14)  评论(0编辑  收藏  举报