主席树(可持久化线段树)

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,q,tot=0;
int a[N],b[N];
int T[N],sum[N<<5],L[N<<5],R[N<<5];
int build(int l,int r)
{
	int rt=++tot;
	int mid=(l+r)>>1;
	if(l<r)
	{
		L[rt]=build(l,mid);
		R[rt]=build(mid+1,r);
	}
	return rt;
}
int update(int pre,int l,int r,int x)
{
	int rt=++tot;
	L[rt]=L[pre];R[rt]=R[pre];sum[rt]=sum[pre]+1;
	
	int mid=(l+r)>>1;
	if(l<r)
	{
		if(x<=mid) L[rt]=update(L[pre],l,mid,x);
		else R[rt]=update(R[pre],mid+1,r,x);
	}
	return rt;
}
int query(int u,int v,int l,int r,int k)
{
	if(l==r) return l;
	int x=sum[L[v]]-sum[L[u]];
	int mid=(l+r)>>1;
	if(x>=k) return query(L[u],L[v],l,mid,k);
	else return query(R[u],R[v],mid+1,r,k-x);	
}
int main()
{
	int q;
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&a[i]);
		b[i]=a[i];
	}
	sort(b+1,b+1+n);
	m=unique(b+1,b+1+n)-b-1;
	T[0]=build(1,m);
	for(int i=1;i<=n;++i)
	{
		a[i]=lower_bound(b+1,b+m+1,a[i])-b;
		T[i]=update(T[i-1],1,m,a[i]);	
	}
	while(q--)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		int p=query(T[x-1],T[y],1,m,z);
		printf("%d\n",b[p]);	
	}
	return 0;
}
posted @ 2021-08-26 15:48  Mint-hexagram  阅读(37)  评论(0编辑  收藏  举报