可持久化线段树

 

 #include <cstdio>
 #include <algorithm>
 using namespace std ;
 const int maxn=200010;
 int a[maxn],b[maxn],blen,n,CNT;
 int sum[maxn<<5],lc[maxn<<5],rc[maxn<<5],rt[maxn<<5];
 
  int update(int k,int l,int r,int x){
 	int t=++CNT,md=(l+r)>>1;
 	lc[t]=lc[k],rc[t]=rc[k],sum[t]=sum[k]+1;
 	
 	if(l==r) return t;
 	if(x<=md) lc[t]=update(lc[t],l,md,x); 
	 else rc[t]=update(rc[t],md+1,r,x);
	 return t;
 }
 
 int query(int l,int r,int x,int y,int kth){
 	int md=(l+r)>>1,t=sum[lc[y]]-sum[lc[x]];
 	if(l==r) return l;
 	if(kth<=t) return query(l,md,lc[x],lc[y],kth);
 	else return query(md+1,r,rc[x],rc[y],kth-t);
 } 
 
 int main(){
 	int p,i,x,y,k,m;
 	scanf("%d%d",&n,&m);
 	for(i=1;i<=n;i++) scanf("%d",a+i),b[i]=a[i];
 	
 	sort(b+1,b+n+1);
 	blen=unique(b+1,b+n+1)-b-1;
 	
 	for(i=1;i<=n;i++){
 		p=lower_bound(b+1,b+blen+1,a[i])-b;
 		
 		rt[i]=update(rt[i-1],1,blen,p);
	 }
	while(m--){
		scanf("%d%d%d",&x,&y,&k);
	printf("%d\n",b[query(1,blen,rt[x-1],rt[y],k)]);
	}
 }
 

 

posted on 2023-06-22 15:00  towboat  阅读(18)  评论(0)    收藏  举报