平衡树求条QAQ
  • 板块学术版
  • 楼主TIERD
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/16 21:08
  • 上次更新2024/10/16 23:04:48
查看原帖
平衡树求条QAQ
932102
TIERD楼主2024/10/16 21:08

就就就一个普通treap。。。但一直过不了QAQ

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+5,INF=1e9;

struct treap{
	int l,r;//左右孩子
	int key;//关键字
	int cnt;//关键字出现次数
	int size;//子树大小
	int rd;//堆随机值
}t[N];

int n,cur,root;

void update(int u){
	t[u].size=t[t[u].l].size+t[t[u].r].size+1;
}

void rturn(int &u){//右旋
	int v=t[u].l;
	t[u].l=t[v].r;
	t[v].r=u;
	update(v);
	update(u);
	u=v;
}

void lturn(int &u){//左旋
	int v=t[u].r;
	t[u].r=t[v].l;
	t[v].l=u;
	update(v);
	update(u);
	u=v;
}

int new_point(int x){//新建一个空结点
	++cur;
	t[cur].key=x;
	t[cur].rd=rand();
	t[cur].size=t[cur].cnt=1;
	return cur;
}

void insert(int &u,int x){
	if(!u){//啥都没有
		u=new_point(x);//新建一个节点
		return;
	}
	if(t[u].key==x)++t[u].cnt;//已经存在则出现次数+1
	else{
		if(x<t[u].key){//递归左子树
			insert(t[u].l,x);
			if(t[u].rd>t[t[u].l].rd)rturn(u);//旋转保持平衡
		}
		else{//同理,递归右子树
			insert(t[u].r,x);
			if(t[u].rd>t[t[u].r].rd)lturn(u);//旋转
		}
	}
	update(u);
}

void remove(int &u,int x){
	if(!u)return;//找不到了,则没有这个点,那么直接return
	if(t[u].key==x){//定位到了
		if(t[u].cnt>1){//关键字出现了多次
			--t[u].cnt;//减去一个就行
			update(u);
			return;
		}
		if(t[u].l||t[u].r){//有儿子
			if(!t[u].r||t[t[u].l].rd>t[t[u].r].rd){//优先级大的补上来
				rturn(u);
				remove(t[u].r,x);
			}
			else{
				lturn(u);
				remove(t[u].l,x);
			}
		}
		else u=0;//发现是叶子节点,直接删
		return;
	}
	if(x<t[u].key)remove(t[u].l,x);
	else remove(t[u].r,x);
	update(u);
}

int get_rank(int u,int x){
	if(!u)return 1;
	if(t[u].key>=x)return get_rank(t[u].l,x);
	return get_rank(t[u].r,x)+t[t[u].l].size+1;
}

int find_rank(int u,int x){
	if(t[t[u].l].size==x-1)return t[u].key;
	else if(t[t[u].l].size>=x)return find_rank(t[u].l,x);
	return find_rank(t[u].r,x-t[t[u].l].size-1);
}

int get_pre(int u,int x){
	if(!u)return -INF;
	if(t[u].key<x)return max(t[u].key,get_pre(t[u].r,x));
	else return get_pre(t[u].l,x);
}

int get_next(int u,int x){
	if(!u)return INF;
	if(t[u].key>x)return min(t[u].key,get_next(t[u].l,x));
	else return get_next(t[u].r,x);
}

int main(){
	scanf("%d",&n);
	while(n--){
		int opt,x;
		scanf("%d%d",&opt,&x);
		if(opt==1)insert(root,x);
		if(opt==2)remove(root,x);
		if(opt==3)printf("%d\n",get_rank(root,x));
		if(opt==4)printf("%d\n",find_rank(root,x));
		if(opt==5)printf("%d\n",get_pre(root,x));
		if(opt==6)printf("%d\n",get_next(root,x));
	}
	return 0;
}

2024/10/16 21:08
加载中...