poj2104 K-th Number 主席树

    裸的主席树,可以见我的上一篇博客,或者见=>seter.is-programmer.com/posts/31907.html

AC代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 100005
using namespace std;

int n,m,cnt,trtot,a[N],val[N],num[N],rt[N],ls[N*80],rs[N*80],sum[N*80];
int find(int x){
	int l=1,r=cnt;
	while (l<r){ int mid=(l+r)>>1; if (val[mid]<x) l=mid+1; else r=mid; }
	return l;
}
void ins(int l,int r,int x,int &y,int v){
	y=++trtot; sum[y]=sum[x]+1; if (l==r) return;
	int mid=(l+r)>>1;
	if (v<=mid){ rs[y]=rs[x]; ins(l,mid,ls[x],ls[y],v); }
	else{ ls[y]=ls[x]; ins(mid+1,r,rs[x],rs[y],v); }
}
int qry(int x,int y,int k){
	x=rt[x-1]; y=rt[y]; int l=1,r=cnt;
	while (l<r){
		int mid=(l+r)>>1,tmp=sum[ls[y]]-sum[ls[x]];
		if (tmp>=k){ r=mid; x=ls[x]; y=ls[y]; }
		else{ l=mid+1; x=rs[x]; y=rs[y]; k-=tmp; }
	}
	return l;
}
int main(){
	scanf("%d%d",&n,&m); int i;
	for (i=1; i<=n; i++){ scanf("%d",&a[i]); num[i]=a[i]; }
	sort(num+1,num+n+1);
	for (i=1; i<=n; i++) if (i==1 || num[i]!=num[i-1]) val[++cnt]=num[i];
	for (i=1; i<=n; i++) ins(1,cnt,rt[i-1],rt[i],find(a[i]));
	while (m--){
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		printf("%d\n",val[qry(x,y,z)]);
	}
	return 0;
}

by lych

2016.2.11



你可能感兴趣的:(主席树)