不开O2,RE on 3,5,6 ,7,8,9,10,11,12
开O2,MLE on 3,5,6 ,7,8,9,10,11,12
#include<bits/stdc++.h>
using namespace std;
//FHQ Treap
const int N = 1e5 + 10;
//树节点的定义
struct treeNode {
int key/*键值*/, pri/*优先级*/;
int ls, rs;/*左右孩子*/
int size;/*以当前节点为根的子树中的节点的数量,用于排名、第k大*/
}t[N];
int cnt/*新建节点的编号*/, root/*根节点*/;
//根据键值x创建一个新的树节点
void newNode(int x) {
t[++cnt].key = x, t[cnt].pri = rand();
t[cnt].ls = t[cnt].rs = 0;
t[cnt].size = 1;
}
//更新节点编号为u的size
void update(int u) {
t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
}
//两大核心/基本操作-分裂与合并
//分裂-权值分裂-时间复杂度-O(logn)
//对于当前树u,将树u中键值小于等于x的都放到左树L,大于x的都放到右树R
void Split(int u/*当前树的树根*/, int x/*键值*/, int& L, int& R) {
if (u == 0) { L = R = 0; return; }
if (t[u].key <= x) {
L = u;
Split(t[u].rs, x, t[u].rs, R);
}
else {
R = u;
Split(t[u].ls, x, L, t[u].ls);
}
update(u);
}
//合并-时间复杂度-O(logn)
int Merge(int L, int R) {
if (L == 0 || R == 0) return L + R;
if (t[L].pri > t[R].pri) {
t[L].rs = Merge(t[L].rs,R);
update(L);
return L;
}
else {
t[R].ls = Merge(L, t[R].ls);
update(R);
return R;
}
}
//六大基本操作
//1.插入
void insert(int x/*键值*/) {
int L, R;
Split(root, x, L, R);
newNode(x);
root = Merge(Merge(L, cnt), R);
}
//2.删除
void del(int x/*键值*/) {
int L, R, p;
Split(root, x, L, R);
Split(L, x - 1, L, p);
p = Merge(t[p].ls, t[p].rs);
root=Merge(Merge(L, p), R);
}
//3.排名
void Rank(int x/*键值*/) {
int L, R;
Split(root, x - 1, L, R);
printf("%d\n", t[L].size + 1);
root = Merge(L, R);
}
//4.第k大
int kth(int u,int k) {
if (k == t[t[u].ls].size + 1) return u;
else if (k > t[t[u].ls].size) return kth(t[u].rs, k - (t[t[u].ls].size + 1));
else kth(t[u].ls, k);
}
//5.前驱
void precursor(int x/*键值*/) {
int L, R;
Split(root, x - 1, L, R);
printf("%d\n", t[kth(L, t[L].size)].key);
root=Merge(L, R);
}
//6.后继
void successor(int x/*键值*/) {
int L, R;
Split(root, x, L, R);
printf("%d\n", t[kth(R, 1)].key);
root = Merge(L, R);
}
int main() {
srand(time(0));
int n; cin >> n;
while (n--) {
int opt, x;
cin >> opt >> x;
switch (opt) {
case 1:insert(x); break;
case 2:del(x); break;
case 3:Rank(x); break;
case 4:printf("%d\n",t[kth(root,x)].key); break;
case 5:precursor(x); break;
case 6:successor(x); break;
}
}
return 0;
}