现在的位置: 首页 > 综合 > 正文

[Bzoj3224]Tyvj 1728 普通平衡树

2018年01月13日 ⁄ 综合 ⁄ 共 1910字 ⁄ 字号 评论关闭
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
using namespace std;
struct data{
	int l,r,num,rnd,s,w;
}tr[100001];
int size,root,ans,n,t,oper;
void update(int k){
	tr[k].s=tr[tr[k].l].s+tr[tr[k].r].s+tr[k].w;
}
void rrotate(int &k){
	int t=tr[k].l;
	tr[k].l=tr[t].r;
	tr[t].r=k;
	tr[t].s=tr[k].s;
	update(k);
	k=t;
}
void lrotate(int &k){
	int t=tr[k].r;
	tr[k].r=tr[t].l;
	tr[t].l=k;
	tr[t].s=tr[k].s;
	update(k);
	k=t;
}
void insert(int &k,int x){
	if(k==0){
		tr[k=++size].rnd=rand();
		tr[k].num=x;
		tr[k].s=tr[k].w=1;
		return;
	}
	tr[k].s++;
	if(tr[k].num==x)tr[k].w++;
	else if(x<tr[k].num){
		insert(tr[k].l,x);
		if(tr[tr[k].l].rnd<tr[k].rnd)
			rrotate(k);
	}
	else{
		insert(tr[k].r,x);
		if(tr[tr[k].r].rnd<tr[k].rnd)
			lrotate(k);
	}
}
void del(int &k,int x){
	if(k==0)return;
	else if(tr[k].num==x){
		if(tr[k].w>1){tr[k].w--;tr[k].s--;return;}
		else if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;
		else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd){
			rrotate(k);del(k,x);
		}
		else{
			lrotate(k);del(k,x);
		}
	}
	else if(x>tr[k].num){
		tr[k].s--;
		del(tr[k].r,x);
	}
	else{
		tr[k].s--;
		del(tr[k].l,x);
	}
}
int ask_rank(int k,int x){
	if(k==0)return 0;
	else if(x==tr[k].num)return tr[tr[k].l].s+1;
	else if(x>tr[k].num)return tr[tr[k].l].s+tr[k].w+ask_rank(tr[k].r,x);
	else return ask_rank(tr[k].l,x);
}
int ask_num(int k,int x){
	if(k==0)return 0;
	else if(x<=tr[tr[k].l].s)return ask_num(tr[k].l,x);
	else if(x>tr[tr[k].l].s+tr[k].w)return ask_num(tr[k].r,x-tr[tr[k].l].s-tr[k].w);
	else return tr[k].num;
}
void ask_before(int k,int x){
	if(k==0)return;
	if(tr[k].num<x){
		ans=k;
		ask_before(tr[k].r,x);
	}
	else ask_before(tr[k].l,x);
}
void ask_after(int k,int x){
	if(k==0)return;
	if(tr[k].num>x){
		ans=k;
		ask_after(tr[k].l,x);
	}
	else ask_after(tr[k].r,x);
}
int main(){
	scanf("%d",&n);
	while(n--){
		scanf("%d%d",&oper,&t);
		switch(oper){
			case 1:{
				insert(root,t);
				break;
			}
			case 2:{
				del(root,t);
				break;
			}
			case 3:{
				printf("%d\n",ask_rank(root,t));
				break;
			}
			case 4:{
				printf("%d\n",ask_num(root,t));
				break;
			}
			case 5:{
				ask_before(root,t);
				printf("%d\n",tr[ans].num);
				break;
			}
			case 6:{
				ask_after(root,t);
				printf("%d\n",tr[ans].num);
				break;
			}
		}
	}
	return 0;
}

抱歉!评论已关闭.