POJ 2104 K-th Number 主席树

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1e5+5;

int N,M;
int A[MAXN];

int has[MAXN];
int htot;
int get(int x){
	int tt = lower_bound(has,has+htot,x)-has;
	return tt+1;
}
int show(int x){
	return has[x-1];
}

struct Node{
	int ls; int rs; int sum; 
}tree[MAXN*30];
int root[MAXN];
int tot; int Ed;
int Build(int l,int r) {
	int rt = tot++;
	tree[rt].sum = 0;
	if(l == r) return rt;
	int m = (l+r) >>1;
	tree[rt].ls = Build(l,m);
	tree[rt].rs = Build(m+1,r);
	return rt;
}
int Update(int pos,int num,int l,int r,int pre) {
	int rt = tot++;
	tree[rt] = tree[pre];
	tree[rt].sum += num;
	if(l == r) return rt;
	int m = (l+r) >>1;
	if(pos <= m) tree[rt].ls = Update(pos,num,l,m,tree[pre].ls);
	else tree[rt].rs = Update(pos,num,m+1,r,tree[pre].rs);
	return rt;
}

int Qans;
void Query(int num,int l,int r,int rt1,int rt2) {
	if(l == r) {
		Qans = r; return;
	}
	int m = (l + r) >>1;
	int tt = tree[tree[rt2].ls].sum - tree[tree[rt1].ls].sum;
	if(tt >= num) Query(num,l,m,tree[rt1].ls,tree[rt2].ls);
   	else Query(num-tt, m+1, r, tree[rt1].rs,tree[rt2].rs);	
}
void Debug(int l,int r,int rt){
	printf("%d %d %d
",l,r,tree[rt].sum);
	if(l == r) {
		return;
	}
	int m = (l+r) >>1;
	Debug(l,m,tree[rt].ls); Debug(m+1,r,tree[rt].rs);
}
int main(){
	while(~scanf("%d %d",&N,&M)) {
		htot = 0;	
		for(int i = 1; i <= N; ++i) { scanf("%d",&A[i]); has[htot ++] = A[i]; }
		sort(has,has+htot); 
		htot = unique(has, has+htot) - has;
		Ed = htot;

		tot = 0; root[0] = Build(1,Ed);
		for(int i = 1; i <= N; ++i) {
			int tt = get(A[i]);
			root[i] = Update(tt, 1, 1, Ed, root[i-1]);
		}
	//	Debug(1,Ed,root[5]); printf("
");
	//	for(int i = 1; i <= N; ++i) printf("%d ",root[i]); printf("
");

		for(int i = 1; i <= M; ++i) {
			int a,b,c; scanf("%d %d %d",&a,&b,&c);
			Query(c,1,Ed,root[a-1],root[b]);
			printf("%d
",show(Qans) );
		}
	}
	return 0;
}


原文地址:https://www.cnblogs.com/Basasuya/p/8433761.html