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';
}
}
}