import java.util.*;
class Main{
static final int range = 10000010;
static final int INF = 0x3f3f3f3f;
static class Node{
int key, val, cnt, size;
Node left, right;
public Node(int key, int val){
this.key = key;
this.val = val;
// System.out.println(val);
this.cnt = this.size = 1;
}
}
static int rand(){
return new Random().nextInt(2*range);
}
static Node root = null;
static Node zig(Node node){//右旋, 返回此时的该位置节点
Node p = node.left;
node.left = p.right;
p.right = node;
pushup(p.right);
pushup(p);
return p;
}
static Node zag(Node node){//左旋
Node p = node.right;
node.right = p.left;
p.left = node;
pushup(p.left);
pushup(p);
return p;
}
static void pushup(Node node){
int lsize, rsize;
lsize = rsize = 0;
if(node.left!=null) lsize = node.left.size;
if(node.right!=null) rsize = node.right.size;
node.size = node.cnt + lsize + rsize;
}
static Node insert(Node node, int key){
if(node==null) return new Node(key, rand());
if(node.key==key) node.cnt++;
if(key<node.key){
node.left = insert(node.left, key);
if(node.left.val>node.val) node = zig(node);
}else if(key>node.key){
node.right = insert(node.right, key);
if(node.right.val>node.val) node = zag(node);
}
pushup(node);
return node;
}
static Node remove(Node node, int key){
if(node==null) return null;
if(key<node.key){
node.left = remove(node.left, key);
pushup(node);
return node;
}
if(key>node.key){
node.right = remove(node.right, key);
pushup(node);
return node;
}
//相等的时候
if(node.cnt>1){
node.cnt--;
pushup(node);
return node;
}
if(node.left==null&&node.right==null) return null;
else{
if(node.left==null){//左旋
node = zag(node);
node.left = remove(node.left, key);
pushup(node);
return node;
}
if(node.right==null){//右旋
node = zig(node);
node.right = remove(node.right, key);
pushup(node);
return node;
}
if(node.left.key>node.right.key){//左孩子上来, 右旋
node = zig(node);
node.right = remove(node.right, key);
}else{//右孩子上来, 左旋
node = zag(node);
node.left = remove(node.left, key);
}
}
pushup(node);
return node;
}
static int getKeyByRang(Node node, int range){
if(node==null) return INF;
Node left = node.left;
Node right = node.right;
int lsize = left==null?0:left.size;
if(lsize>=range) return getKeyByRang(node.left, range);
if(lsize+node.cnt>=range) return node.key;
return getKeyByRang(node.right, range - lsize - node.cnt);
}
static int getRangByKey(Node node, int key){
if(node==null) return 0;
Node left = node.left;
int lsize = left==null?0:left.size;
if(key>node.key) return lsize + node.cnt + getRangByKey(node.right, key);
if(key==node.key) return lsize + 1;
return getRangByKey(node.left, key);
}
static int getPre(Node node, int key){
if(node==null) return -INF;
if(key<=node.key) return getPre(node.left, key);
return Math.max(node.key, getPre(node.right, key));
}
static int getNext(Node node, int key){
if(node==null) return INF;
if(key>=node.key) return getNext(node.right, key);
return Math.min(node.key, getNext(node.left, key));
}
static void build(){
root = new Node(-INF, rand());
root.right = new Node(INF, rand());
pushup(root);
if(root.val<root.right.val) root = zag(root);
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int res = 0;
build();
while(n-->0){
int opt = in.nextInt();
int op = in.nextInt();
if(opt==1)
root = insert(root, op);
else if(opt==2)
root = remove(root, op);
else if(opt==3)
System.out.println(getRangByKey(root, op)-1);
else if(opt==4)
System.out.println(getKeyByRang(root, op+1));
else if(opt==5)
System.out.println(getPre(root, op));
else
System.out.println(getNext(root, op));
}
}
}
深受学习,感谢