旋转Treap:如果把rk换成siz
查看原帖
旋转Treap:如果把rk换成siz
651786
yyc_楼主2023/3/16 20:19
insert:
if(u->ch[0]->rk > u->rk) rota(u,0)

->

insert:
if(u->ch[0]->siz > u->ch[1]->siz + lim) rota(u,0)

复杂度是否依旧有保证,这样相较于rk有什么缺点,为什么不这么维护

完整代码:

#include<bits/stdc++.h>
#define ls s[0]
#define rs s[1]
#define lim 3
using namespace std;
const int maxn = 1e5+10;
int cnt,n,rt,x; char opt;
struct node { int val,cnt,siz,s[2]; }t[maxn];
inline void upsiz(int u) { u[t].siz = u[t].cnt + u[t].ls[t].siz + u[t].rs[t].siz; }
inline void setval(int u,int val) { u[t].val = val; u[t].siz = u[t].cnt = 1; }
inline void rota(int& u,bool r) { //r : new rt
	int c = u[t].s[r];
	u[t].s[r] = c[t].s[!r];
	c[t].s[!r] = u;
	upsiz(u),upsiz(c);
	u = c;
}
void insert(int& u,int val) {
	if(!u) { setval(u = ++cnt,val); return; }
	if(u[t].val == val) { ++u[t].siz,++u[t].cnt; return; }
	if(val < u[t].val) {
		insert(u[t].ls,val);
		if(u[t].ls[t].siz > u[t].rs[t].siz + lim) rota(u,0);
	} else {
		insert(u[t].rs,val);
		if(u[t].rs[t].siz > u[t].ls[t].siz + lim) rota(u,1);
	}
	upsiz(u);
}
void del(int& u,int val) {
	if(u[t].val == val) {
		if(u[t].cnt > 1) { --u[t].siz,--u[t].cnt; return; }
		int a = u[t].ls, b = u[t].rs;
		if(!a || !b) { u = a | b; return; }
		bool c = (a[t].siz < b[t].siz);
		rota(u,c);
		del(u[t].s[!c],val);
		upsiz(u); return;
	}
	if(val < u[t].val) del(u[t].ls,val);
	else del(u[t].rs,val);
	upsiz(u);
}
int getrk(int u,int val) { // < val
	if(!u) return 0;
	int less = u[t].ls[t].siz;
	if(val == u[t].val) return less;
	if(val < u[t].val) return getrk(u[t].ls,val);
	else return less + u[t].cnt + getrk(u[t].rs,val);
}
int getval(int u,int k) {
	int less = u[t].ls[t].siz;
	if(k <= less) return getval(u[t].ls,k);
	if(k <= u[t].cnt + less) return u[t].val;
	return getval(u[t].rs,k - less - u[t].cnt);
}
signed main() {
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n;
	while(n--) {
		cin>>opt>>x;
		switch(opt) {
			case '1': insert(rt,x); 						break;
			case '2': del(rt,x);							break;
			case '3': cout<<getrk(rt,x)+1<<'\n';			break;
			case '4': cout<<getval(rt,x)<<'\n';				break;
			case '5': cout<<getval(rt,getrk(rt,x))<<'\n'; 	break;
			case '6': cout<<getval(rt,getrk(rt,x+1)+1)<<'\n';
		}
	}
}
2023/3/16 20:19
加载中...