妹子Treap事件求助,赏关注
查看原帖
妹子Treap事件求助,赏关注
868063
_Coffice_楼主2023/6/2 19:01

结果不固定,但都有几个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;
}
2023/6/2 19:01
加载中...