求助红黑树
查看原帖
求助红黑树
400781
Troubadour楼主2021/6/12 10:25

RT,wa#3,TLE#4~#11,看起来像是删除操作以及根的判定有误,求大佬查错

#include<bits/stdc++.h>
namespace RBT
{
	struct tree
	{
		int val, color, fa, ch[2], size;
	}f[2000005];
#define fa(x) (f[x].fa)
#define ls(x) (f[x].ch[0])
#define rs(x) (f[x].ch[1])
#define size(x) (f[x].size)
#define color(x) (f[x].color)
	int root, cnt;
	bool identify(int p)
	{
		return rs(fa(p)) == p;
	}
	void update(int p)
	{
		size(p) = size(ls(p)) + size(rs(p)) + 1;
	}
	void rotate_update(int p)
	{
		color(ls(p)) = color(rs(p)) = 1;
		color(p) = 0;
	}
	void connect(int son, int fa, int k)
	{
		fa(son) = fa;
		f[fa].ch[k] = son;
	}
	void rotate(int x)
	{
		int y = fa(x), z = fa(y), yk = identify(x), zk = identify(y), b = f[x].ch[yk ^ 1];
		connect(b, y, yk);
		connect(y, x, yk ^ 1);
		connect(x, z, zk);
		update(y);
		update(x);
		if (fa(x) == 0)
		{
			root = x;
			if (color(root))
			{
				color(root) = 0;
			}
		}
		else if (fa(y) == 0 && y)
		{
			root = y;
			if (color(root))
			{
				color(root) = 0;
			}
		}
		else if (fa(z) == 0 && z)
		{
			root = z;
			if (color(root))
			{
				color(root) = 0;
			}
		}
		else if (fa(b) == 0 && b)
		{
			root = b;
			if (color(root))
			{
				color(root) = 0;
			}
		}
		//if(color(x)==1&&(color(ls(x))||color(rs(x))))
	}
	void slovedoublered(int x);
	void sloveadd(int x)
	{
		int y = fa(x), z = fa(y), yk = identify(x), zk = identify(y);
		int w = f[z].ch[zk ^ 1];
		if (w == 0);
		else if (color(w) == 1)
		{
			slovedoublered(x);
		}
		else if (color(w) == 0)
		{
			if (yk != zk)
			{
				rotate(x);
				rotate(x);
				rotate_update(x);
			}
			else
			{
				rotate(y);
				rotate_update(y);
			}
		}
		if (fa(x) == 0)
		{
			root = x;
			if (color(root))
			{
				color(root) = 0;
			}
		}
		if (fa(y) == 0 && y)
		{
			root = y;
			if (color(root))
			{
				color(root) = 0;
			}
		}
	}
	void slovedoublered(int x)
	{
		int y = fa(x), z = fa(y), chk = identify(y);
		int w = f[z].ch[chk ^ 1];
		color(w) = color(y) = 0;
		color(z) = 1;
		sloveadd(z);
	}
	void insert(int x)
	{
		int p = root;
		if (root == 0)
		{
			root = ++cnt;
			f[cnt].size = 1;
			f[cnt].val = x;
			++cnt;
			f[cnt].val = -1;
			connect(cnt, root, 0);
			++cnt;
			f[cnt].val = -1;
			connect(cnt, root, 1);
			return;
		}
		while (f[p].val != -1)
		{
			if (f[p].val >= x)
			{
				p = f[p].ch[0];
			}
			else
			{
				p = f[p].ch[1];
			}
		}
		f[p].color = 1;
		f[p].val = x;
		f[p].size = 1;
		cnt++;
		f[cnt].val = -1;
		connect(cnt, p, 0);
		cnt++;
		f[cnt].val = -1;
		connect(cnt, p, 1);
		sloveadd(p);
		while (p != 0)
		{
			update(p);
			p = fa(p);
		}
	}
	int kth(int k)
	{
		int p = root;
		while (1)
		{
			if (f[ls(p)].size + 1 < k)
			{
				k -= size(ls(p)) + 1;
				p = rs(p);
			}
			else if (size(ls(p)) >= k)
			{
				p = ls(k);
			}
			else
			{
				return f[p].val;
			}
		}
	}
	int rank(int k)
	{
		int res = 0, p = root;
		while (1)
		{
			if (k < f[p].val)
			{
				p = ls(p);
			}
			else if (k > f[p].val)
			{
				res += size(ls(p)) + 1;
				p = rs(p);
			}
			else
			{
				return res + size(ls(p)) + 1;
			}
		}
	}
	void slovedel(int x)
	{
		if (x == root)return;
		int y = fa(x), z = fa(y), yk = identify(x), zk = identify(y);
		int b = f[y].ch[yk ^ 1];
		if (color(b) == 0)
		{
			if (color(ls(b)) == color(rs(b)) && color(ls(b)) == 0)
			{
				if (color(y) == 1)
				{
					std::swap(color(b), color(y));
				}
				else
				{
					color(b) = 1;
					slovedel(y);
				}
			}
			else
			{
				int bk = identify(b);
				if (bk == 0)
				{
					if (color(ls(b)) == 0)
					{
						rotate(b);
						std::swap(color(b), color(rs(b)));
						slovedel(x);
					}
					else
					{
						//rotate(y);
						rotate(b);
						std::swap(color(y), color(b));
						color(ls(b)) = 0;
					}
				}
				else
				{
					if (color(rs(b)) == 0)
					{
						rotate(b);
						std::swap(color(b), color(ls(b)));
						slovedel(x);
					}
					else
					{
						//rotate(y);
						rotate(b);
						std::swap(color(y), color(b));
						color(rs(b)) = 0;
					}
				}
			}
		}
		else
		{
			rotate(b);
			std::swap(color(y), color(b));
			slovedel(x);
		}
		if (fa(x) == 0)
		{
			root = x;
			if (color(root))
			{
				color(root) = 0;
			}
		}
		if (fa(y) == 0 && y)
		{
			root = y;
			if (color(root))
			{
				color(root) = 0;
			}
		}
	}
	void del(int x)
	{
		int p = root;
		if (root == 0)return;
		while (f[p].val != x)
		{
			if (x <= f[p].val)
			{
				p = ls(p);
			}
			else
			{
				p = rs(p);
			}
		}
		if (f[ls(p)].val == -1 && f[rs(p)].val == -1)
		{
			int yk = identify(p);
			connect(ls(p), fa(p), yk);
			if (color(p) == 0)
			{
				slovedel(ls(p));
			}
			while (p)
			{
				update(p);
				p = fa(p);
			}
		}
		else if ((f[ls(p)].val == -1 && f[rs(p)].val != -1) || (f[ls(p)].val != -1 && f[rs(p)].val == -1))
		{
			if (f[rs(p)].val == -1)
			{
				int k = identify(p);
				connect(ls(p), fa(p), k);
				color(ls(p)) = 0;
			}
			else
			{
				int k = identify(p);
				connect(rs(p), fa(p), k);
				color(ls(p)) = 0;
			}
			while (p)
			{
				update(p);
				p = fa(p);
			}
		}
		else if (f[ls(p)].val != -1 && f[rs(p)].val != -1)
		{
			int q = ls(p);
			while (f[rs(q)].val != -1)
			{
				q = rs(q);
			}
			std::swap(f[p].val, f[q].val);
			f[q].val = -1;
			f[q].size = 0;
			slovedel(p);
			while (q)
			{
				update(q);
				q = fa(q);
			}
		}
	}
	int pre(int k)
	{
		int p = root, pre = 0;
		while (f[p].val != -1)
		{
			if (f[p].val < k)
			{
				pre = f[p].val;
				p = rs(p);
			}
			else p = ls(p);
		}
		return pre;
	}
	int nxt(int k)
	{
		int p = root, nxt = 0;
		while (f[p].val != -1)
		{
			if (f[p].val > k)
			{
				nxt = f[p].val, p = ls(p);
			}
			else
			{
				p = rs(p);
			}
		}
		return nxt;
	}
}
namespace CCCP
{
	using namespace RBT;
	int n, m, flag;
	using std::cin;
	void work()
	{
		cin >> n;
		for (int i = 1;i <= n;i++)
		{
			int opt, x;
			cin >> opt >> x;
			switch (opt)
			{
			case 1:
				insert(x);
				break;
			case 2:
				del(x);
				break;
			case 3:
				std::cout << rank(x) << '\n';
				break;
			case 4:
				std::cout << kth(x) << '\n';
				break;
			case 5:
				std::cout << pre(x) << '\n';
				break;
			case 6:
				std::cout << nxt(x) << '\n';
			}
		}
	}
}
int main()
{
	return CCCP::work(), 0;
}
2021/6/12 10:25
加载中...