treap板子30pts求调,玄关
查看原帖
treap板子30pts求调,玄关
542389
Fcersoka楼主2024/8/30 09:09

rt, 记录

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, INF = 2147483647;
int root; 
class Treap
{
private:
	class TreapNode
	{
	public:
		int l, r, val, dat, cnt, size;
	}treap[N];
	int tot;
	void update(int p)
	{
		treap[p].size = treap[treap[p].l].size + treap[treap[p].r].size + treap[p].cnt;
	}
	int create_new_node(int val)
	{
		treap[++tot].val = val;
		treap[tot].dat = rand();
		treap[tot].cnt = treap[tot].size = 1;
		return tot;
	} 
	void zig(int &p)
	{
		int q = treap[p].l;
		treap[p].l = treap[q].r;
		treap[q].r = p;
		p = q;
		update(treap[p].r);
		update(p); 
	}
	void zag(int &p)
	{
		int q = treap[p].r;
		treap[p].r = treap[q].l;
		treap[q].l = p;
		p = q;
		update(treap[p].l);
		update(p);
	}

public:
	void build()
	{
		tot = 0;
		create_new_node(-INF);
		create_new_node(INF);
		root = 1;
		treap[1].r = 2;
		update(root);
	}
	int get_rank(int p, int val)
	{
		if (!p)
		{
			return 0; 
		}
		if (val == treap[p].val)
		{
			return treap[treap[p].l].size + 1;
		}
		if (val < treap[p].val)
		{
			return get_rank(treap[p].l, val);
		}
		return get_rank(treap[p].r, val) + treap[treap[p].l].size + treap[p].cnt;
	} 
	int get_val(int p, int rank)
	{
		if (!p)
		{
			return INF;	
		} 
		if (treap[treap[p].l].size >= rank)
		{
			return get_val(treap[p].l, rank);
		}
		if (treap[treap[p].l].size + treap[p].cnt >= rank)
		{
			return treap[p].val;
		}
		return get_val(treap[p].r, rank - treap[treap[p].l].size - treap[p].cnt);
	}
	int get_precursor(int val)
	{
		int ans = 1, p = root;
		while (p)
		{
			if (val == treap[p].val)
			{
				if (treap[p].l)
				{
					p = treap[p].l;
					while (treap[p].r)
					{
						p = treap[p].r;
					}
					ans = p;
				}
				break; 
			}
			if (treap[p].val < val && treap[p].val > treap[ans].val)
			{
				ans = p;	
			}
			p = val < treap[p].val ? treap[p].l : treap[p].r;
		}
		return treap[ans].val;
	}
	int get_next(int val)
	{
		int ans = 2, p = root;
		while (p)
		{
			if (val == treap[p].val)
			{
				if (treap[p].r)
				{
					p = treap[p].r;
					while (treap[p].l)
					{
						p = treap[p].l;
					}
					ans = p;
				}
				break;
			}
			if (treap[p].val > val && treap[p].val < treap[ans].val)
			{
				ans = p;
			}
			p = val < treap[p].val ? treap[p].l : treap[p].r;
		}
		return treap[ans].val;
	}
	void insert(int &p, int val)
	{
		if (!p)
		{
			p = create_new_node(val);
			return ;
		}
		if (val == treap[p].val)
		{
			treap[p].cnt++;
			update(p);
			return ;
		}
		if (val < treap[p].val)
		{
			insert(treap[p].l, val);
			if (treap[p].dat < treap[treap[p].l].dat)
			{
				zig(p);
			}
		}
		else
		{
			insert(treap[p].r, val);
			if (treap[p].dat < treap[treap[p].r].dat)
			{
				zag(p);
			}
		}
	}
    void remove(int &p, int val)
    {
        if (!p)
        {
            return ;
        }
        if (val == treap[p].val)
        {
            if (treap[p].cnt > 1)
            {
                treap[p].cnt--;
                update(p);
                return ;
            }
            if (treap[p].l || treap[p].r)
            {
                if (!treap[p].r || treap[treap[p].l].dat > treap[treap[p].r].dat)
                {
                    zig(p);
                    remove(treap[p].r, val);
                }
                else
                {
                    zag(p);
                    remove(treap[p].l, val);
                }
                update(p);
            }
            else
            {
                p = 0;
            }
            return ;
        }
        val < treap[p].val ? remove(treap[p].l, val) : remove(treap[p].r, val);
        update(p);
    }
};
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int q;
	cin >> q;
	Treap t;
	t.build(); 
	while (q--)
	{
		int op, x;
		cin >> op >> x;
		switch(op)
		{
		case 1:
            t.insert(root, x);
			break;
		case 2:
            t.remove(root, x);
			break;
		case 3:
            cout << t.get_rank(root, x) - 1 << '\n';
			break;
		case 4:
            cout << t.get_val(root, x + 1) << '\n';
			break;
		case 5:
            cout << t.get_precursor(x) << '\n';
			break;
        default:
            cout << t.get_next(x) << '\n';
            break;
		}
	}
	return 0;	
} 
2024/8/30 09:09
加载中...