rt,代码氧气中毒
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAXN = 1e5 + 1e2;
int n;
struct tree
{
int ls, rs, size, val, cnt, rank;
}t[MAXN];
int root, sum;
int ans;
inline int read()
{
int x = 0, fl = 1; char ch = getchar();
while ( !isdigit(ch) ) { if(ch == '-') fl = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = x * 10 + (ch - '0'); ch = getchar(); }
return x * fl;
}
void l_rotate (int &p)
{
int tmp = t[p].rs;
t[p].rs = t[tmp].ls;
t[tmp].ls = p;
t[tmp].size = t[p].size;
t[p].size = t[t[p].ls].size + t[t[p].rs].size + t[p].cnt;
p = tmp;
}
void r_rotate (int &p)
{
int tmp = t[p].ls;
t[p].ls = t[tmp].rs;
t[tmp].rs = p;
t[tmp].size = t[p].size;
t[p].size = t[t[p].ls].size + t[t[p].rs].size + t[p].cnt;
p = tmp;
}
void insert (int &p, int k)
{
if (!p)
{
p = ++ sum;
t[p].size = 1;
t[p].val = k;
t[p].cnt = 1;
t[p].rank = rand();
return;
}
t[p].size ++;
if (t[p].val == k) t[p].cnt ++;
else if (t[p].val > k)
{
insert (t[p].ls, k);
if (t[t[p].ls].rank < t[p].rank) r_rotate (p);
}
else
{
insert (t[p].rs, k);
if (t[t[p].rs].rank < t[p].rank) l_rotate (p);
}
}
bool del (int &p, int k)
{
if (!p) return false;
if (t[p].val == k)
{
if (t[p].cnt > 1)
{
t[p].cnt --;
t[p].size --;
return true;
}
if (t[p].ls == 0 || t[p].rs == 0) { p = t[p].ls + t[p].rs; return true; }
if (t[t[p].ls].rank < t[t[p].rs].rank)
{
r_rotate (p);
del (p, k);
}
else
{
l_rotate (p);
del (p, k);
}
}
else if (t[p].val > k)
{
bool succ = del (t[p].ls, k);
if (succ) t[p].size --;
return succ;
}
else
{
bool succ = del (t[p].rs, k);
if (succ) t[p].size --;
return succ;
}
}
int query_rank (int p, int k)
{
if (!p) return 0;
if (t[p].val == k) return t[t[p].ls].size + 1;
else if (t[p].val > k) return query_rank (t[p].ls, k);
else return t[t[p].ls].size + t[p].cnt + query_rank (t[p].rs, k);
}
int query_num (int p, int k)
{
if (!p) return 0;
if (k <= t[t[p].ls].size) return query_num (t[p].ls, k);
else if (k > t[t[p].ls].size + t[p].cnt) return query_num (t[p].rs, k - t[t[p].ls].size - t[p].cnt);
else return t[p].val;
}
void query_pre (int p, int k)
{
if (!p) return;
if (t[p].val < k) { ans = t[p].val; query_pre(t[p].rs, k); }
else query_pre (t[p].ls, k);
}
void query_sub (int p, int k)
{
if (!p) return;
if (t[p].val > k) { ans = t[p].val; query_sub(t[p].ls, k); }
else query_sub (t[p].rs, k);
}
void work()
{
n = read();
while (n --)
{
int opt, x;
opt = read(); x = read();
if (opt == 1) insert (root, x);
else if (opt == 2) del (root, x);
else if (opt == 3) printf ("%d\n", query_rank(root, x) );
else if (opt == 4) printf ("%d\n", query_num(root, x) );
else if (opt == 5) { ans = 0; query_pre(root, x); printf("%d\n", ans); }
else { ans = 0; query_sub(root, x); printf("%d\n", ans); }
}
}
int main()
{
work();
return 0;
}