Rt,求助myRank函数
#include <bits/stdc++.h>
#define MAXN 2000010
#define alpha 0.7
using namespace std;
int cnt = 0,
rt = 0,
lc[MAXN],
rc[MAXN],
wn[MAXN],
w[MAXN],
s[MAXN],
sz[MAXN],
sd[MAXN],
ldr[MAXN];
void calc(int k){
//重新计算以k为根的子树大小
s[k] = s[lc[k]] + s[rc[k]] + 1;
sz[k] = sz[lc[k]] + sz[rc[k]] + wn[k];
sd[k] = sd[lc[k]] + sd[rc[k]] + (wn[k] != 0);
}
bool canRbd(int k){
//计算节点k是否需要重构
return wn[k] && (alpha * s[k] <= (double)max(s[lc[k]], s[rc[k]]) ||
(double)sd[k] <= alpha * s[k]);
}
void flatten(int& ldc, int k){
//中序遍历以k为根的子树
if(!k) return;
flatten(ldc, lc[k]);
if(wn[k]) ldr[ldc++] = k;
flatten(ldc, rc[k]);
}
int __rebuild(int l, int r){
//将[l,r)重构成树,返回根节点
int mid = (l + r) >> 1;
if(l >= r) return 0;
lc[ldr[mid]] = __rebuild(l, mid);
rc[ldr[mid]] = __rebuild(mid + 1, r);
calc(ldr[mid]);
return ldr[mid];
}
void rebuild(int& k){
//重构节点k的全过程
int ldc = 0;
flatten(ldc, k);
k = __rebuild(0, ldc);
}
void ins(int& k, int val){
//在以k为根的子树内插入val
if(!k){
k = ++cnt;
if(!rt) rt = 1;
w[k] = val;
lc[k] = rc[k] = 0;
wn[k] = s[k] = sz[k] = sd[k] = 1;
}else{
if(wn[k] == val)
wn[k]++;
else if(w[k] < val)
ins(rc[k], val);
else
ins(lc[k], val);
calc(k);
if(canRbd(k)) rebuild(k);
}
}
void del(int& k, int val){
if(!k) return;
else{
if(w[k] == val && wn[k]){
wn[k]--;
}else if(w[k] < val)
del(rc[k], val);
else
del(lc[k], val);
calc(k);
if(canRbd(k)) rebuild(k);
}
}
int myUpper(int k, int val){
if(!k) return 1;
else if(w[k] == val && wn[k])
return sz[lc[k]] + wn[k] + 1;
else if(val < w[k])
return myUpper(lc[k], val);
else return sz[lc[k]] + wn[k] + myUpper(rc[k], val);
}
int myLower(int k, int val){
if(!k) return 0;
else if(w[k] == val && wn[k] != 0)
return sz[lc[k]];
else if(w[k] < val)
return sz[lc[k]] + wn[k] + myLower(rc[k], val);
else return myLower(lc[k], val);
}
int myAt(int k, int p) {
// 以 k 为根的子树中,名次为 p 的权值
if (!k)
return 0;
else if (sz[lc[k]] < p && p <= sz[lc[k]] + wn[k])
return w[k];
else if (sz[lc[k]] + wn[k] < p)
return myAt(rc[k], p - sz[lc[k]] - wn[k]);
else
return myAt(lc[k], p);
}
int myRank(int k, int val){
if(!k) return 1;
else if(w[k] < val) return myRank(rc[k], val) + sz[lc[k]] + wn[k];
else return myRank(lc[k], val);
}
int pre(int k, int val){
return myAt(k, myLower(k, val));
}
int post(int k, int val){
return myAt(k, myUpper(k, val));
}
int main(){
//freopen("QWQ.out", "w", stdout);
int n;
cin >> n;
while(n--){
int opt, x, tot = 0;
cin >> opt >> x;
if(opt > 2) tot++;
switch(opt){
case 1: ins(rt, x); break;
case 2: del(rt, x); break;
case 3: cout << myRank(rt, x) << '\n'; break;
case 4: cout << myAt(rt, x) << '\n'; break;
case 5: cout << pre(rt, x) << '\n'; break;
case 6: cout << post(rt, x) << '\n'; break;
}
}
return 0;
}