Treap求调
查看原帖
Treap求调
1279263
hzc0829楼主2025/1/2 13:07
#include<bits/stdc++.h>
using namespace std;
mt19937 rnd(998244353);
const int INF=2147483647;
int n;
int idx,root;
struct node{
	int l,r;
	int key,val;
	int cnt,size;
}tr[100010];
void push_up(int rt){
	tr[rt].size=tr[tr[rt].l].size+tr[tr[rt].r].size+tr[rt].cnt;
}
int new_node(int val){
	tr[++idx].val=val;
	tr[idx].key=rnd();
	tr[idx].cnt=1;
	tr[idx].size=1;
	return idx;
}
void build(){
	new_node(-INF);
	root=idx;
	new_node(INF);
	tr[root].r=idx;
	push_up(root);
}
void zig(int &p){
	int q=tr[p].l;
	tr[p].l=tr[q].r;
	tr[q].r=p;
	p=q;
	push_up(tr[p].r);
	push_up(p);
}
void zag(int &p){
	int q=tr[p].r;
	tr[p].r=tr[q].l;
	tr[q].l=p;
	p=q;
	push_up(tr[p].l);
	push_up(p);
}
void insert(int &rt,int val){
	if(!rt){
		rt=new_node(val);
		return;
	}
	if(tr[rt].val==val){
		tr[rt].cnt++;
		return;
	}
	if(tr[rt].val>val){
		insert(tr[rt].l,val);
		if(tr[tr[rt].l].key>tr[rt].key){
			zig(rt);
		}
		return;
	}
	if(tr[rt].val<val){
		insert(tr[rt].r,val);
		if(tr[tr[rt].r].key>tr[rt].key){
			zag(rt);
		}
		return;
	}
	push_up(rt);
}
void remove(int &rt,int val){
	if(!rt){
		return;
	}
	if(tr[rt].val==val){
		if(tr[rt].cnt>1){
			tr[rt].cnt--;
		}
		if(tr[rt].l||tr[rt].r){
			if(!tr[rt].r||tr[tr[rt].l].key>tr[tr[rt].r].key){
				zig(rt);
				remove(tr[rt].r,val);
			}else{
				zag(rt);
				remove(tr[rt].l,val);
			}
		}else{
			rt=0;	
		}
	}else if(tr[rt].val>val){
		remove(tr[rt].l,val);
	}else{
		remove(tr[rt].r,val);
	}
	push_up(rt);
}
int get_rank(int &rt,int val){
	if(!rt){
		return -1;
	}
	if(tr[rt].val==val){
		return tr[tr[rt].l].size+1;
	}
	if(tr[rt].val>val){
		return get_rank(tr[rt].l,val);
	}
	return tr[tr[rt].l].size+tr[rt].cnt+get_rank(tr[rt].r,val);
}
int get_val(int &rt,int rank){
	if(!rt){
		return -1;
	}
	if(tr[tr[rt].l].size>=rank){
		return get_val(tr[rt].l,rank);
	}
	if(tr[tr[rt].l].size+tr[rt].cnt>=rank){
		return tr[rt].val;
	}
	return get_val(tr[rt].r,rank-tr[tr[rt].l].size-tr[rt].cnt);
}
int get_prev(int &rt,int val){
	if(!rt){
		return -1;
	}
	if(tr[rt].val>=val){
		return get_prev(tr[rt].l,val);
	}
	return max(tr[rt].val,get_prev(tr[rt].r,val));
}
int get_next(int &rt,int val){
	if(!rt){
		return -1;
	}
	if(tr[rt].val<=val){
		return get_next(tr[rt].l,val);
	}
	return min(tr[rt].val,get_next(tr[rt].l,val));
}
int main(){
	cin>>n;
	while(n--){
		int opt,x;
		cin>>opt>>x;
		if(opt==1){
			insert(root,x);
		}else if(opt==2){
			remove(root,x);
		}else if(opt==3){
			cout<<get_rank(root,x)-1<<endl;
		}else if(opt==4){
			cout<<get_val(root,x+1)<<endl;
		}else if(opt==5){
			cout<<get_prev(root,x)<<endl;
		}else{
			cout<<get_next(root,x)<<endl;
		}
	}
	return 0;
}

rt,平衡树板子

2025/1/2 13:07
加载中...