rt,不知名原因 RE
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int n;
const int LF = 0, RT = 1;
struct Tree
{
int size, val, cnt, rank;
Tree *ch[2];
Tree(int val) : val (val), cnt (1), size (1)
{
ch[0] = ch[1] = NULL;
rank = rand();
}
void upd_size()
{
size = cnt;
if (ch[0] != NULL) size += ch[0]->size;
if (ch[1] != NULL) size += ch[1]->size;
}
};
Tree *root = NULL;
int Q_pre, Q_sub;
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 _rotate (Tree *&cur, int dir)
{
Tree *tmp = cur->ch[!dir];
cur->ch[!dir] = tmp->ch[dir];
tmp->ch[dir] = cur;
tmp->upd_size(), cur->upd_size();
cur = tmp;
}
void insert (Tree *&cur, int k)
{
if (cur == NULL)
{
cur = new Tree(k);
return;
}
if (k == cur->val)
{
cur->cnt ++;
cur->size ++;
}
else if (k < cur->val)
{
insert (cur->ch[0], k);
if (cur->ch[0]->rank < cur->rank) _rotate (cur, RT);
cur->upd_size();
}
else
{
insert (cur->ch[1], k);
if (cur->ch[1]->rank < cur->rank) _rotate (cur, LF);
cur->upd_size();
}
}
void del (Tree *&cur, int k)
{
if (k == cur->val)
{
if (cur->cnt > 1) { cur->cnt --, cur->size --; return; }
int flag = 0;
flag |= ( (cur->ch[0] != NULL) << 1);
flag |= (cur->ch[1] != NULL);
Tree *tmp = cur;
if (!flag) { delete cur; cur = NULL; }
else if (flag == 1) { cur = tmp->ch[1]; delete tmp; }
else if (flag == 2) { cur = tmp->ch[0]; delete tmp; }
else/* if (flag == 3)*/
{
int dir = cur->ch[0]->rank < cur->ch[1]->rank ? RT : LF;
_rotate (cur, dir);
del (cur->ch[!dir], k);
cur->upd_size();
}
}
else if (k < cur->val)
{
del (cur->ch[0], k);
cur->upd_size();
}
else
{
del (cur->ch[1], k);
cur->upd_size();
}
}
int query_rank (Tree *cur, int k)
{
int ls_size = cur->ch[0] == NULL ? 0 : cur->ch[0]->size;
if (k == cur->val) return ls_size + 1;
else if (k < cur->val)
{
if (cur->ch[0] != NULL) return query_rank (cur->ch[0], k);
else return 1;
}
else
{
if (cur->ch[1] != NULL) return ls_size + cur->cnt + query_rank (cur->ch[1], k);
else return cur->size + 1;
}
}
int query_num (Tree *cur, int rk)
{
int ls_size = cur->ch[0] == NULL ? 0 : cur->ch[0]->size;
if (rk <= ls_size and cur->ch[0] != NULL) return query_num (cur->ch[0], rk);
else if (rk > ls_size + cur->cnt and cur->ch[1] != NULL) return query_num (cur->ch[1], rk - ls_size - cur->cnt);
else return cur->val;
}
int query_pre (Tree *cur, int k)
{
if (k <= cur->val)
{
if (cur->ch[0] != NULL) return query_pre (cur->ch[0], k);
}
else
{
Q_pre = cur->val;
if (cur->ch[1] != NULL) query_pre (cur->ch[1], k);
return Q_pre;
}
return -114514;
}
int query_sub (Tree *cur, int k)
{
if (k >= cur->val)
{
if (cur->ch[1] != NULL) return query_sub (cur->ch[1], k);
}
else
{
Q_sub = cur->val;
if (cur->ch[0] != NULL) query_sub (cur->ch[0], k);
return Q_sub;
}
return 1919810;
}
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) printf ("%d\n", query_pre(root, x) );
else printf ("%d\n", query_sub(root, x) );
}
}
int main()
{
work();
return 0;
}