rt.以下代码没有判断没前驱的情况,但仍然通过了本题:
#include <bits/stdc++.h>
int n;
int op, x;
const int MAXN = 1e5 + 5;
const double alpha = 0.75;
int tot;
int root;
int data[MAXN];
int lc[MAXN], rc[MAXN];
int cnt[MAXN];
int s[MAXN], sz[MAXN], sd[MAXN];
int ldr[MAXN];
void C(int k) {
s[k] = s[lc[k]] + s[rc[k]] + 1;
sz[k] = sz[lc[k]] + sz[rc[k]] + cnt[k];
sd[k] = sd[lc[k]] + sd[rc[k]] + (cnt[k] != 0);
}
bool check(int k) {
return cnt[k] && (alpha * s[k] <= (double)std::max(s[lc[k]], s[rc[k]]) || (double)sd[k] <= alpha * s[k]);
}
void R_f(int &ldc, int k) {
if (!k) return;
R_f(ldc, lc[k]);
if (cnt[k]) {
ldr[ldc++] = k;
}
R_f(ldc, rc[k]);
}
int R_b(int l, int r) {
int mid = l + r >> 1;
if (l >= r) {
return 0;
}
lc[ldr[mid]] = R_b(l, mid);
rc[ldr[mid]] = R_b(mid + 1, r);
C(ldr[mid]);
return ldr[mid];
}
void R(int &k) {
int ldc = 0;
R_f(ldc, k);
k = R_b(0, ldc);
}
void I(int &k, int p) {
if (!k) {
k = ++tot;
if (!root) root = 1;
data[k] = p;
lc[k] = rc[k] = 0;
cnt[k] = s[k] = sz[k] = sd[k] = 1;
} else {
if (data[k] == p)
cnt[k]++;
else if (data[k] < p)
I(rc[k], p);
else
I(lc[k], p);
C(k);
if (check(k)) R(k);
}
}
void D(int &k, int p) {
if (!k)
return;
else {
if (data[k] == p) {
if (cnt[k]) cnt[k]--;
} else if (data[k] < p) {
D(rc[k], p);
} else {
D(lc[k], p);
}
C(k);
if (check(k)) R(k);
}
}
int UprGrt(int k, int p) {
if (!k)
return 0;
else if (data[k] == p && cnt[k])
return sz[lc[k]];
else if (data[k] < p)
return sz[lc[k]] + cnt[k] + UprGrt(rc[k], p);
else
return UprGrt(lc[k], p);
}
int UprBd(int k, int p) {
if (!k)
return 1;
else if (data[k] == p && cnt[k])
return sz[lc[k]] + 1 + cnt[k];
else if (p < data[k])
return UprBd(lc[k], p);
else
return sz[lc[k]] + cnt[k] + UprBd(rc[k], p);
}
int At(int k, int p) {
if (!k)
return 2147483647;
else if (sz[lc[k]] < p && p <= sz[lc[k]] + cnt[k])
return data[k];
else if (sz[lc[k]] + cnt[k] < p)
return At(rc[k], p - sz[lc[k]] - cnt[k]);
else
return At(lc[k], p);
}
int lst(int k, int p) {
return At(k, UprGrt(k, p));
}
int nxt(int k, int p) {
return At(k, UprBd(k, p));
}
int main() {
// freopen("in.in", "r", stdin);
// freopen("out.out", "w", stdout);
// int k=0;
scanf("%d", &n);
for (; n; n--) {
scanf("%d%d", &op, &x);
// if(op!=1&&op!=2) std::cerr<<++k<<" "<<op<<std::endl;
if (op == 5) {
I(root, x);
} else if (op == 1) {
printf("%d\n", UprGrt(root, x) + 1);
} else if (op == 2) {
printf("%d\n", At(root, x));
} else if (op == 3) {
printf("%d\n", lst(root, x));
} else {
printf("%d\n", nxt(root, x));
}
}
return 0;
}
而这组数据能卡掉上述程序:
输入:
1
3 1
输出:
-2147483647
上述程序输出:
2147483647
请求添加Hack数据