RT,为啥只AC了最后一个点?
#include <bits/stdc++.h>
#define MAXN 1000010
#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;
lc[k] = rc[k] = 0;
wn[k] = s[k] = sz[k] = sd[k] = 1;
w[k] = val;
}else{
if(wn[k] == val)
wn[k]++;
else if(wn[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){
if(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] != 0)
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 rk){
if(!k) return 0;
else if(sz[lc[k]] < rk && rk - sz[lc[k]] <= wn[k])
return w[k];
else if(sz[lc[k]] + wn[k] < rk)
return myAt(rc[k], rk - wn[k] - sz[lc[k]]);
else return myAt(lc[k], rk);
}
int myRank(int k, int val){
return myLower(k, val) + 1;
}
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(){
int n;
cin >> n;
while(n--){
int opt, x;
cin >> opt >> x;
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;
}