不开O2 MLE,开了有时60,有时0
代码:
#include <iostream>
#include <ctime>
using namespace std;
const int N = 100010,INF = 2e8;
struct node {
int l,r;
int key,val;
int size;
}tr[N];
int root,idx;
int n,m;
int a[N];
int new_node (int key) {
tr[++idx] = {0,0,key,rand (),1};
return idx;
}
void push_up (int u) {
tr[u].size = tr[tr[u].l].size + tr[tr[u].r].size + 1;
}
void build () {
new_node (-INF),new_node (INF);
root = 1,tr[1].r = 2;
if (tr[1].val < tr[2].val) root = 2,tr[2].l = 1;
push_up (root);
}
void split_key (int u,int key,int &x,int &y) {
if (!u) {
x = y = 0;
return ;
}
if (tr[u].key <= key) {
x = u;
split_key (tr[u].r,key,tr[x].r,y);
push_up (x);
}
else {
y = u;
split_key (tr[u].l,key,x,tr[y].l);
push_up (y);
}
}
int merge (int x,int y) {
if (!x || !y) return x + y;
if (tr[x].val > tr[y].val) {
tr[x].r = merge (tr[x].r,y);
push_up (x);
return x;
}
tr[y].l = merge (x,tr[y].l);
push_up (y);
return y;
}
void insert (int key) {
int x,y;
split_key (root,key,x,y);
root = merge (merge (x,new_node (key)),y);
}
void erase (int key) {
int x,y,z;
split_key (root,key,x,z),split_key (x,key - 1,x,y);
y = merge (tr[y].l,tr[y].r);
root = merge (x,merge (y,z));
}
int get_rank_by_key (int p,int key) {
if (!p) return 0;
if (tr[p].key == key) return tr[tr[p].l].size + 1;
if (tr[p].key > key) return get_rank_by_key (tr[p].l,key);
return tr[tr[p].l].size + 1 + get_rank_by_key (tr[p].r,key);
}
int get_key_by_rank (int p,int rank) {
if (!p) return INF;
if (rank <= tr[tr[p].l].size) return get_key_by_rank (tr[p].l,rank);
if (rank <= tr[tr[p].l].size + 1) return tr[p].key;
return get_key_by_rank (tr[p].r,rank - tr[tr[p].l].size - 1);
}
int get_prev (int p,int key) {
if (!p) return -INF;
if (tr[p].key >= key) return get_prev (tr[p].l,key);
return max (tr[p].key,get_prev (tr[p].r,key));
}
int get_next (int p,int key) {
if (!p) return INF;
if (tr[p].key <= key) return get_next (tr[p].r,key);
return min (tr[p].key,get_next (tr[p].l,key));
}
int main () {
srand (time (0));
build ();
cin >> n;
while (n--) {
int op,x;
cin >> op >> x;
if (op == 1) insert (x);
else if (op == 2) erase (x);
else if (op == 3) cout << get_rank_by_key (root,x) - 1 << endl;
else if (op == 4) cout << get_key_by_rank (root,x + 1) << endl;
else if (op == 5) cout << get_prev (root,x) << endl;
else cout << get_next (root,x) << endl;
}
return 0;
}