Splay 求调
查看原帖
Splay 求调
911417
_Z_F_R_楼主2023/11/25 18:28

rt

/**                                                                                        {        
 * problem: Splay        
 * site: \
 * author: _Z_F_R_
 * date: 2023-10-29 21:41:46    
 **/          
#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 100005;
struct Splay_Tree
{
	struct tNode
	{
		int fa, lc, rc;
		int val, cnt, size;
	}tree[N << 1];
	int root, cntnode;
	bool isrc(int x)
	{
		return tree[tree[x].fa].rc == x;
	}
	void Update(int x)
	{
		tree[x].size = tree[tree[x].lc].size + tree[tree[x].rc].size + tree[x].cnt;
	}
	void Zag(int x)
	{
		int fa = tree[x].fa;
		int gfa = tree[fa].fa;
		bool sg = isrc(fa);
		tree[fa].rc = tree[x].lc;
		if(tree[fa].rc)
			tree[tree[fa].rc].fa = fa;
		tree[fa].fa = x, tree[x].lc = fa, tree[x].fa = gfa;
		if(gfa)
		{
			if(sg)
				tree[gfa].rc = x;
			else
				tree[gfa].lc = x;
		}
	}
	void Zig(int x)
	{
		int fa = tree[x].fa;
		int gfa = tree[fa].fa;
		bool sg = isrc(fa);
		tree[fa].lc = tree[x].rc;
		if(tree[fa].lc)
			tree[tree[fa].lc].fa = fa;
		tree[fa].fa = x, tree[x].rc = fa, tree[x].fa = gfa;
		if(gfa)
		{
			if(sg)
				tree[gfa].rc = x;
			else
				tree[gfa].lc = x;
		}
	}
	void Rotate(int x)
	{
		int fa = tree[x].fa;
		bool sf = isrc(x);
		if(sf)
			Zag(x);
		else
			Zig(x);
		Update(fa), Update(x);
	}
	void Splay(int x, int goal)
	{
		if(goal == 0)
			root = x;
		while(true)
		{
			int fa = tree[x].fa;
			int gfa = tree[fa].fa;
			if(fa == goal)
				break;
			if(gfa != goal)
			{
				if(isrc(x) == isrc(fa))
					Rotate(fa);
				else
					Rotate(x);
			}
			Rotate(x);
		}
	}
	int Find_Pos(int x, int val)
	{
		if(val < tree[x].val && tree[x].lc)
			return Find_Pos(tree[x].lc, val);
		if(val > tree[x].val && tree[x].rc)
			return Find_Pos(tree[x].rc, val);
		return x;
	}
	int Find_Num(int rank)
	{
		int x = root, rrank = rank;
		while(true)
		{
			if(rrank <= tree[tree[x].lc].size)
				x = tree[x].lc;
			else
			{
				rrank -= tree[tree[x].lc].size;
				if(rrank <= tree[x].cnt)
					return tree[x].val;
				rrank -= tree[x].cnt, x = tree[x].rc;
			}
		}
	}
	int Find_Rank(int val)
	{
		int x = root, ans = 0;
		while(tree[x].val != val)
		{
			if(!x)
				return ans + 1;
			if(val < tree[x].val)
				x = tree[x].lc;
			else
				ans += tree[tree[x].lc].size + tree[x].cnt, x = tree[x].rc;
		}
		if(tree[x].lc)
			ans += tree[tree[x].lc].size;
		return ans + 1;
	}
	int tans;
	void Dfs_Pre(int x)
	{
		if(tree[x].rc)
			Dfs_Pre(tree[x].rc);
		if(tans)
			return ;
		tans = tree[x].val;
	}
	int Find_Pre(int x, int val, bool is_rc)
	{
		tans = 0;
		if(!is_rc)
			return Find_Pre(tree[x].fa, val, tree[tree[x].fa].rc == x);
		if(tree[x].val < val)
			return tree[x].val;
		if(tree[x].lc)
		{
			Dfs_Pre(tree[x].lc);
			return tans;
		}
		return Find_Pre(tree[x].fa, val, tree[tree[x].fa].rc == x);
	}
	void Dfs_Nxt(int x)
	{
		if(tree[x].lc)
			Dfs_Nxt(tree[x].lc);
		if(tans)
			return ;
		tans = tree[x].val;
	}
	int Find_Nxt(int x, int val, bool is_lc)
	{
		tans = 0;
		if(!is_lc)
			return Find_Nxt(tree[x].fa, val, tree[tree[x].fa].lc == x);
		if(tree[x].val > val)
			return tree[x].val;
		if(tree[x].rc)
		{
			Dfs_Nxt(tree[x].rc);
			return tans;
		}
		return Find_Nxt(tree[x].fa, val, tree[tree[x].fa].lc == x);
	}
	void Add_Node(int val, int fa)
	{
		cntnode++;
		tree[cntnode].lc = tree[cntnode].rc = 0;
		tree[cntnode].size = tree[cntnode].cnt = 1;
		tree[cntnode].fa = fa, tree[cntnode].val = val;
		if(fa)
		{
			if(val < tree[fa].val)
				tree[fa].lc = cntnode;
			else
				tree[fa].rc = cntnode;
		}
	}
	void Add(int val)
	{
		int x = root, fa = 0;
		while(x && tree[x].val != val)
			if(tree[x].val > val)
				fa = x, x = tree[x].lc;
			else
				fa = x, x = tree[x].rc;
		if(!x)
		{
			Add_Node(val, fa);
			Splay(cntnode, 0);
			return ;
		}
		tree[x].cnt++;
	}
	void Del(int val)
	{
		int prex = Find_Pos(root, Find_Pre(Find_Pos(root, val), val, true));
		int nxtx = Find_Pos(root, Find_Nxt(Find_Pos(root, val), val, true));
		Splay(prex, 0);
		Splay(nxtx, prex);
		Print();
		if(tree[tree[nxtx].lc].cnt > 1)
		{
			tree[tree[nxtx].lc].cnt--;
			Splay(tree[nxtx].lc, 0);
		}
		else
			tree[nxtx].lc = 0;
		Update(nxtx), Update(prex);
	}
	void Print()
	{
		printf("%d\n", root);
		int i;
		for(i = 1; i <= cntnode; i++)
			printf("%d : fa : %d lc : %d rc : %d cnt : %d val : %d size : %d\n", i, tree[i].fa, tree[i].lc, tree[i].rc, tree[i].cnt, tree[i].val, tree[i].size);
	}
}bst;

int main()
{
	freopen("P3369_4.in", "r", stdin);
	int n;
	scanf("%d", &n);
	while(n--)
	{
		int op, val;
		scanf("%d %d", &op, &val);
		if(op == 1)
			bst.Add(val);
		else if(op == 2)
			bst.Del(val);
		else if(op == 3)
			printf("%d\n", bst.Find_Rank(val));
		else if(op == 4)
			printf("%d\n", bst.Find_Num(val));
		else if(op == 5)
			printf("%d\n", bst.Find_Pre(bst.Find_Pos(bst.root, val), val, true));
		else
			printf("%d\n", bst.Find_Nxt(bst.Find_Pos(bst.root, val), val, true));
		// bst.Print();
	}
}
2023/11/25 18:28
加载中...