结果不固定,但都有几个RE
#include<bits/stdc++.h>
using namespace std;
struct node
{
node* ch[2];
int val;
int cnt;
int rank;
int sz;
};
void renew(node* &p)
{
p->sz = p->cnt;
if(p->ch[0] != NULL)
{
p->sz += p->ch[0]->sz;
}
if(p->ch[1] != NULL)
{
p->sz += p->ch[1]->sz;
}
}
node* t = NULL;
void rotate_left(node* &p)
{
node* tmp = p->ch[1];
p->ch[1] = tmp->ch[0];
tmp->ch[0] = p;
renew(tmp);
renew(p);
p = tmp;
}
void rotate_right(node* &p)
{
node* tmp = p->ch[0];
p->ch[0] = tmp->ch[1];
tmp->ch[1] = p;
renew(tmp);
renew(p);
p = tmp;
}
void add(node* &p,int val)
{
if(p == NULL)
{
p = new node;
p->val = val;
p->cnt = 1;
p->ch[0] = p->ch[1] = NULL;
p->rank = rand();
p->sz = 1;
return ;
}
else if(p->val == val)
{
p->cnt++;
p->sz++;
return ;
}
else if(val < p->val)
{
add(p->ch[0],val);
if(p->ch[0]->rank < p->rank)
{
rotate_right(p);
}
}
else
{
add(p->ch[1],val);
if(p->ch[1]->rank < p->rank)
{
rotate_left(p);
}
}
renew(p);
}
void print(node* p)
{
if(p == NULL)
{
return ;
}
print(p->ch[0]);
for(int i=1;i<=p->cnt;i++) cout << p->val << " ";
print(p->ch[1]);
}
void del(node* &p)
{
if(p == NULL)
{
return ;
}
del(p->ch[0]);
del(p->ch[1]);
delete p;
p = NULL;
}
int op5(node* p,int x)
{
node* tmp = p;
int max_ = -1000000007;
while(! (tmp == NULL))
{
if(tmp->val < x)
{
max_ = max(max_,tmp->val);
tmp = tmp->ch[1];
}
else
{
tmp = tmp->ch[0];
}
}
return max_;
}
int op6(node* p,int x)
{
node* tmp = p;
int min_ = 1000000007;
while(! (tmp == NULL))
{
if(tmp->val > x)
{
min_ = min(min_,tmp->val);
tmp = tmp->ch[0];
}
else
{
tmp = tmp->ch[1];
}
}
return min_;
}
int op3(node* p,int x)
{
node* tmp = p;
int ans = 1;
while(! (tmp == NULL))
{
if(tmp->val < x)
{
if(tmp->ch[0] != NULL) ans += tmp->ch[0]->sz;
ans += tmp->cnt;
tmp = tmp->ch[1];
}
else
{
tmp = tmp->ch[0];
}
}
return ans;
}
int op4(node* p,int x) // 查找排名为x的值
{
int ls; // 左子树大小
if(p->ch[0] == NULL)
{
ls = 0;
}
else
ls = p->ch[0]->sz;
if(x <= ls) // 如果排名<=左子树的大小,说明结果在左子树
{
return op4(p->ch[0],x); // 在左子树查找
}
else if(x <= ls+p->cnt) // 在根节点
{
// 排名 >= 左子树的大小,
// 并且 <= 左子树的大小 + 根节点的重复次数
// 说明在根节点
return p->val; // 直接返回
}
else // 说明在右子树
{
// 将排名转化为对于右子树的排名
// 直接把排名减去左子树的大小和根节点的重复数量
return op4(p->ch[1],x-ls-p->cnt);
}
}
void erase(node* &p,int x)
{
if(x < p->val) // 值更小,查找左子树
{
erase(p->ch[0],x);
renew(p);
}
else if(x > p->val) // 值更大,查找右子树
{
erase(p->ch[1],x);
renew(p);
}
else // 找到节点,开始删除
{
if(p->cnt > 1) // 重复,直接减少重复次数
{
p->cnt--;
p->sz--;
return ;
}
else if(p->ch[0] == NULL && p->ch[1] == NULL)
// 没有子节点,直接删除
{
delete p;
p = NULL;
}
else if(p->ch[0] != NULL && p->ch[1] == NULL) // 有左无右
{
// 把左子结点设为根
p = p->ch[0];
return ;
}
else if(p->ch[0] == NULL && p->ch[1] != NULL) // 有右无左
{
// 把右子结点设为根
p = p->ch[1];
return ;
}
else // 旋转再删除
{
if(p->ch[0]->rank < p->ch[1]->rank)
// 左子结点优先级更高
{
rotate_right(p); // 右旋上去
erase(p->ch[0],x); // 继续删除
}
else
{
rotate_left(p); // 左旋上去
erase(p->ch[1],x); // 继续删除
}
renew(p); // 更新
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
srand(time(NULL));
int n;
cin >> n;
for(int i=1;i<=n;i++)
{
int op;
cin >> op;
if(op == 1)
{
int a;
cin >> a;
add(t,a);
}
else if(op == 5)
{
int x;
cin >> x;
cout << op5(t,x) << endl;
}
else if(op == 6)
{
int x;
cin >> x;
cout << op6(t,x) << endl;
}
else if(op == 3)
{
int x;
cin >> x;
cout << op3(t,x) << endl;
}
else if(op == 4)
{
int x;
cin >> x;
cout << op4(t,x) << endl;
}
else if(op == 2)
{
int x;
cin >> x;
erase(t,x);
}
}
// print(t);
del(t);
return 0;
}