关于平衡树板子
  • 板块学术版
  • 楼主HEIMOFA
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/9/8 17:49
  • 上次更新2023/11/2 22:20:05
查看原帖
关于平衡树板子
929819
HEIMOFA楼主2023/9/8 17:49

那道模板

为什么算法竞赛进阶指南的代码这里不是一过不了

#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
int tot,root;
const int N=1e5+5,INF=0x3f3f3f3f;
struct Node{
	int rank,data,siz,sum;
	int l,r;
};
struct Treap{
	Node a[N];
	int New(int val){
		a[++tot].rank=rand(),a[tot].data=val;
		a[tot].siz=a[tot].sum=1;
		a[tot].l=a[tot].r=0;
		return tot;
	}
	void pushup(int key){
		a[key].siz=a[a[key].l].siz+a[a[key].r].siz+a[key].sum;
	}
	void zag(int &key){
		int son=a[key].r;
		a[key].r=a[son].l,a[son].l=key;
		key=son;
		pushup(a[key].l),pushup(key);
	}
	void zig(int &key){
		int son=a[key].l;
		a[key].l=a[son].r,a[son].r=key;
		key=son;
		pushup(a[key].r),pushup(key);
	}
	void build(){
		tot=0;
		New(-INF),New(INF);
		root=1,a[1].r=2;
		pushup(root);
	}
	int get_rank_val(int key,int x){
		if(key==0) return 1;//就是这里
		if(x==a[key].data) return a[a[key].l].siz+1;
		if(x<a[key].data) return get_rank_val(a[key].l,x);
		return get_rank_val(a[key].r,x)+a[a[key].l].siz+a[key].sum;
	}
	int get_val_rank(int key,int x){
		if(key==0) return INF;
		if(a[a[key].l].siz>=x) return get_val_rank(a[key].l,x);
		if(a[a[key].l].siz+a[key].sum>=x) return a[key].data;
		return get_val_rank(a[key].r,x-a[a[key].l].siz-a[key].sum);
	}
	int get_pre(int x){
		int ans=1,key=root;
		while(key){
			if(a[key].data==x){
				if(a[key].l){
					key=a[key].l;
					while(a[key].r>0) key=a[key].r;
					ans=key;
				}
				break;
			}
			if(a[key].data<x&&a[key].data>a[ans].data) ans=key;
			key=x<a[key].data?a[key].l:a[key].r;
		}
		return a[ans].data;
	}
	int get_next(int x){
		int ans=2,key=root;
		while(key){
			if(a[key].data==x){
				if(a[key].r){
					key=a[key].r;
					while(a[key].l>0) key=a[key].l;
					ans=key;
				}
				break;
			}
			if(a[key].data>x&&a[key].data<a[ans].data) ans=key;
			key=x<a[key].data?a[key].l:a[key].r;
		}
		return a[ans].data;
	}
	void insert(int &key,int x){
		if(!key){
			key=New(x);
			return ;
		}
		if(a[key].data==x){
			a[key].sum++,pushup(key);
			return ;
		}
		if(a[key].data>x){
			insert(a[key].l,x);
			if(a[a[key].l].rank>a[key].rank) zig(key);
		}
		else{
			insert(a[key].r,x);
			if(a[a[key].r].rank>a[key].rank) zag(key);
		}
		pushup(key);
	}
	void erase(int &key,int x){
		if(key==0) return ;
		if(a[key].data==x){
			if(a[key].sum>1){
				a[key].sum--,pushup(key);
				return ;
			}
			if(a[key].l||a[key].r){
				if(a[key].r==0||a[a[key].l].rank>a[a[key].r].rank) zig(key),erase(a[key].r,x);
				else zag(key),erase(a[key].l,x);
				pushup(key);
			}
			else key=0;
			return ;
		}
		x<a[key].data?erase(a[key].l,x):erase(a[key].r,x);
		pushup(key);
	}
}T;

int main()
{
	T.build();
	int n;scanf("%d",&n);
	while(n--){
		int op,x;
		scanf("%d%d",&op,&x);
		if(op==1) T.insert(root,x);
		if(op==2) T.erase(root,x);
		if(op==3) printf("%d\n",T.get_rank_val(root,x)-1);
		if(op==4) printf("%d\n",T.get_val_rank(root,x+1));
		if(op==5) printf("%d\n",T.get_pre(x));
		if(op==6) printf("%d\n",T.get_next(x));
	}
	return 0;
}
2023/9/8 17:49
加载中...