treap 16
查看原帖
treap 16
289056
北射天狼楼主2022/2/22 17:13
#include <bits/stdc++.h>
using namespace std;
int zzp;//zzp ak ioi %%%
int cnt=0;
int root=0;
struct tree{
	int lc,rc;
	int amo,siz;
	int pri,val;
}tr[100001];
void pushup(int p){
	tr[p].siz=tr[tr[p].lc].siz+tr[tr[p].rc].siz+tr[p].amo;
}
void zig(int &p){//右旋 
	int q=tr[p].lc;
	tr[p].lc=tr[q].rc;
	tr[q].rc=p;
	pushup(p);
	p=q; 
}
void zag(int &p){//左旋 
	int q=tr[p].rc;
	tr[p].rc=tr[q].lc;
    tr[q].lc=p;
    pushup(p);
	p=q; 
}/*
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
ssssss
插入 xx 数
删除 xx 数(若有多个相同的数,因只删除一个)
查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 )
查询排名为 xx 的数
求 xx 的前驱(前驱定义为小于 xx,且最大的数)
求 xx 的后继(后继定义为大于 xx,且最小的数)
*/
int node(int val){
	tr[++cnt].val=val;
	tr[cnt].pri=rand();
	tr[cnt].rc=tr[cnt].lc=0;
	tr[cnt].amo=1;
	tr[cnt].siz=1;
	return cnt;
}
void insert(int &p,int val){
	if (!p){
		p=node(val);
		return ;
	}
	if (val==tr[p].val)    {
	    tr[p].amo++;
	}
	if (val<tr[p].val){
		insert(tr[p].lc,val);
		if (tr[p].pri<tr[tr[p].lc].pri)    zig(p);
	}
	if (val>tr[p].val){
		insert(tr[p].rc,val);
		if (tr[p].pri<tr[tr[p].rc].pri)    zag(p);
	}
	pushup(p);
}
void dele(int &p,int val){
	if (!p)    return ;
	tr[p].siz--;
	if (val==tr[p].val){
		if (tr[p].amo>1)    tr[p].amo--;
		else {
			if (!tr[p].lc||!tr[p].lc){
				p=tr[p].lc+tr[p].rc; 
			} else if (tr[tr[p].lc].pri>tr[tr[p].rc].pri){
				zig(p);
				dele(tr[p].rc,val);
				return ;
			} else {
				zag(p);
				dele(tr[p].lc,val);
				return ;
			}
		}
	}
	if (val<tr[p].val){
		dele(tr[p].lc,val);
	} else {
		dele(tr[p].rc,val);
	}
	pushup(p);
}
/*
void erase(int &now,int data)
{
	t[now].siz--;
	if(t[now].data==data)
	{
		if(t[now].left==0&&t[now].right==0)
		{
			now=0;
			return ;
		}
		if(t[now].left==0||t[now].right==0)
		{
			now=t[now].left+t[now].right;
			return ;
		}
		if(t[t[now].left].value<t[t[now].right].value)
		{
			right_rorate(now);
			erase(t[now].right,data);
			return ;
		}
		else
		{
			left_rorate(now);
			erase(t[now].left,data);
			return ;
		}
	}
	if(t[now].data>=data)
	{
		erase(t[now].left,data);
	}
	else
	{
		erase(t[now].right,data);
	}
	up(now);
}
*/
int rank1(int p,int val){
	if (!p)    return 0;
	if (tr[p].val==val){
		return tr[tr[p].lc].siz+1;
	}
	if (tr[p].val<val)
	    return rank1(tr[p].lc,val);
	else{
		return rank1(tr[p].rc,val)+tr[tr[p].lc].siz+tr[p].amo;
	}
}
int derank(int p,int val){
	if (!p)    return 0;
	if (tr[tr[p].lc].siz>val)    return derank(tr[p].lc,val);
	if (tr[tr[p].lc].siz+tr[p].amo>=val)
	    return tr[p].val;
	return derank(tr[p].rc,val-tr[tr[p].lc].siz-tr[p].amo);
}
int pre(int val){
	int p=root;
	int res=0;
	while(p){
		if (tr[p].val<val){
			res=tr[p].val;
			p=tr[p].rc;
		}
		else 
		    p=tr[p].lc;
	}
	return res;
}
int next(int val){
	int p=root;
	int res=0;
	while (p){
		if (tr[p].val>val){
			res=tr[p].val;
			p=tr[p].lc;
		}
		else 
		    p=tr[p].rc; 
    }  
	return res;
	
}
int main()
{
	srand(time(NULL));
	cin>>zzp;
	for (int i=1;i<=zzp;i++){
		int opt,x;
		cin>>opt>>x;
		if (opt==1)	insert(root,x); 
		if (opt==2) dele(root,x);
		if (opt==3)   cout<<rank1(root,x)<<endl;
		if (opt==4)   cout<<derank(root,x)<<endl; 
		if (opt==5)    cout<<pre(x)<<endl;
		if (opt==6)    cout<<next(x)<<endl;
	}

	return 0;
} //insert&&rank

题目通道

2022/2/22 17:13
加载中...