[TJOI2010]中位数

平衡树插入和查询,水题 

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100010;
int n,root,pool,m;
char bb,b,c;
struct node{
	int size,v,pri,cnt,lc,rc;
	#define s(x) a[x].size
	#define v(x) a[x].v
	#define p(x) a[x].pri
	#define c(x) a[x].cnt
	#define lc(x) a[x].lc
	#define rc(x) a[x].rc
}a[N];
inline void zag(int &x){
	int y=lc(x);
	lc(x)=rc(y);
	rc(y)=x;
	s(y)=s(x);
	s(x)=s(lc(x))+s(rc(x))+c(x);
	x=y;
}
inline void zig(int &x){
	int y=rc(x);
	rc(x)=lc(y);
	lc(y)=x;
	s(y)=s(x);
	s(x)=s(lc(x))+s(rc(x))+c(x);
	x=y;
}
inline void Insert(int &k,const int &key){
	if(!k){
		k=++pool;v(k)=key;p(k)=rand();
		lc(k)=rc(k)=0;c(k)=s(k)=1;
		return;
	}
	s(k)++;
	if(v(k)==key) c(k)++;	
	  else{
		if(v(k)>key){
			Insert(lc(k),key);
			if(p(lc(k))<p(k)) zag(k);
		}
		else{
			Insert(rc(k),key);
			if(p(rc(k))<p(k)) zig(k);
		}
	}
	return;
}
inline int QueryKth(int k){
	int x=root;
	while(x){
		if(s(lc(x))<k&&k<=s(lc(x))+c(x)) return v(x);
		 else if(k<=s(lc(x))) x=lc(x);
		      else k=k-s(lc(x))-c(x),x=rc(x);
	}
	return 99;
}
inline void print(int k){
	if(!k) return;
	print(lc(k));
	printf("%d ",v(k));
	print(rc(k));
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		Insert(root,x);
	}
	scanf("%d",&m);
	while(m--){
		int x;
		char s[4];
		scanf("%s",s);
		if(s[0]=='a') {
			scanf("%d",&x);
			Insert(root,x);
		}
		else{
			if(s(root)%2){
				printf("%d\n",QueryKth(s(root)/2+1));
			}
			else printf("%d\n",QueryKth(s(root)/2));
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_42198700/article/details/88778892