记录编号 425327 评测结果 RRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
题目名称 [HZOI 2016]tb的平衡树 最终得分 0
用户昵称 Gravatar하루Kiev 是否通过 未通过
代码语言 C++ 运行时间 0.003 s
提交时间 2017-07-15 08:20:27 内存使用 1.46 MiB
显示代码纯文本
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<time.h>
#define maxn 50005
#define inf 0x3f3f3f3f
using namespace std;
struct tree{
	int l,r,no,size,tot,rd;
}e[maxn];int zz,root,n,opt,s,fro,bac;
void l_swap(int &root){
	 int newroot=e[root].r;
	 e[root].r=e[newroot].l;
	 e[newroot].l=root;
	 e[newroot].size=e[root].size;
	 e[root].size=e[e[root].l].size+e[e[root].r].size+e[root].tot;
	 root=newroot;
}
void r_swap(int &root){
	 int newroot=e[root].l;
	 e[root].l=e[newroot].r;
	 e[newroot].r=root;
	 e[newroot].size=e[root].size;
	 e[root].size=e[e[root].l].size+e[e[root].r].size+e[root].tot;
	 root=newroot;
}
void insert_(int &root,int x){
     if(!root){
     	root=++zz;
     	e[root].no=x;
     	e[root].size=e[root].tot=1;
     	e[root].rd=rand();//随机数维护堆性质 
     	return;
     }
     e[root].size++;
     if(e[root].no==x) e[root].tot++;
     else{
	     if(e[root].no>x){
	     	insert_(e[root].l,x);
	     	if(e[e[root].l].rd<e[root].rd)
              r_swap(root);
         }
         else{
         	insert_(e[root].r,x);
         	if(e[e[root].r].rd<e[root].rd)
         	   l_swap(root);
         
		 }
	}
}
void delete_(int &root,int no){
     if(!root) return;
     if(e[root].no==no){
     	if(e[root].tot>1){
		   e[root].tot--;
		   e[root].size--;
		   return;
	    }//有很多个相同数,删除一个不影响树的结构
     	if(e[root].l*e[root].r==0) root=e[root].l+e[root].r;//子树只有一个,直接抬升子树节点
        else{
		   if(e[e[root].l].rd<e[e[root].r].rd)
		      r_swap(root);
		   else l_swap(root);
		   //维护堆性质后,继续删除节点 
	       delete_(root,no);
		}
     }
     else{
     	 e[root].size--;
     	 if(no>e[root].no) delete_(e[root].r,no);
     	 else delete_(e[root].l,no); 
     }
}	
void anc_(int &root,int no){
	 if(!root) return;
	 if(e[root].no<no){
	 	fro=e[root].no;
	 	anc_(e[root].r,no);
	 }
	 else anc_(e[root].l,no);
}
void bac_(int &root,int no){
	 if(!root) return;
	 if(e[root].no>no){
	 	bac=e[root].no;
	 	bac_(e[root].l,no);
	 }
	 else bac_(e[root].r,no);
}
int rank_(int &root,int no){
     if(!root) return 0;
     if(e[root].no==no){
     	return e[e[root].l].size+1;
     }
     else if(e[root].no>no) return rank_(e[root].l,no);
	      else return e[e[root].l].size+e[root].tot+rank_(e[root].r,no);
}
int num_(int &root,int rank){
	if(!root) return 0;
	if(e[e[root].l].size+1<=rank&&e[e[root].l].size+e[root].tot>=rank)
	   return e[root].no;
	if(e[e[root].l].size>=rank) return num_(e[root].l,rank);	
    if(e[e[root].l].size<rank)  return num_(e[root].r,rank-e[root].tot-e[e[root].l].size);
    
}	
int main(){
	freopen("phs.in","r",stdin);
	freopen("phs.out","w",stdout);
	scanf("%d",&n);
	while(n--){
	      scanf("%d%d",&opt,&s);
		  switch(opt){
		         case 1: insert_(root,s);break;
				 case 2: delete_(root,s);break;
				 case 3: printf("%d\n",rank_(root,s));break;
				 case 4: printf("%d\n",num_(root,s));break;
				 case 5: fro=-inf;anc_(root,s);printf("%d\n",fro);break;
				 case 6: bac=-inf;bac_(root,s);printf("%d\n",bac);break;
		  }
	}
    //system("pause");
	return 0; 
}