一个空序列,支持过插入一个数,删除一个数,要查询当前序列第 k 大是哪个数,或者比 x 小的数有几个。
Treap 模版题
#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 1500000000
using namespace std;
typedef long long LL;
const int N = 300005;
struct treap {
int ch[2], val, sz; unsigned int wt;
void Set(int vl) { val = vl, wt = rand() * rand() * rand(), sz = 1; }
} t[N];
int rt, n, tz, q;
void update(int x) {
t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz + 1;
}
void rot(int &x, bool ty) {
int y = t[x].ch[ty]; t[x].ch[ty] = t[y].ch[!ty], t[y].ch[!ty] = x;
update(x), update(y), x = y;
}
void add(int &x, int val) {
if (!x) { t[x = ++ tz].Set(val); return ; }
if (t[x].val == val) return ;
bool ty = val > t[x].val;
add (t[x].ch[ty], val);
(t[t[x].ch[ty]].wt > t[x].wt) ? rot(x, ty) : update(x);
}
void del(int &x, int val) {
if (!x) return ;
if (t[x].val == val) {
bool ty = t[t[x].ch[1]].wt > t[t[x].ch[0]].wt;
if (!t[x].ch[ty]) { x = 0; return ; }
rot(x, ty), del(t[x].ch[!ty], val);
} else del(t[x].ch[val > t[x].val], val);
update(x);
}
int kth(int k) {
int x = rt;
if (t[x].sz < k) return inf;
for (; k != t[t[x].ch[0]].sz + 1;) (k <= t[t[x].ch[0]].sz) ? x = t[x].ch[0] : (k -= t[t[x].ch[0]].sz + 1, x = t[x].ch[1]);
return t[x].val;
}
int Count(int x) {
if (!x) return 0;
if (t[x].val < q) return Count(t[x].ch[1]) + t[t[x].ch[0]].sz + 1;
else return Count(t[x].ch[0]);
}
void init() {
scanf("%d", &n);
}
void doit() {
for (int i = 1; i <= n; i ++) {
int x; char ty;
scanf (" %c %d", &ty, &x);
if (ty == 'I') add(rt, x);
else if (ty == 'D') del(rt, x);
else if (ty == 'K') {
x = kth(x);
(x != inf) ? printf ("%d\n", x) : puts("invalid");
}
else q = x, printf ("%d\n", Count(rt));
}
}
int main()
{
init();
doit();
return 0;
}