萌新刚学OI,简单平衡树板子50pts玄关求调
查看原帖
萌新刚学OI,简单平衡树板子50pts玄关求调
542389
Fcersoka楼主2024/11/3 19:26
#include <bits/stdc++.h>
using namespace std;
const int N = 2.5e5 + 5, INF = 2147483647;
int n;
struct People
{
	int score, time;
	string name;
	bool operator < (const People &other) const
	{
		return score == other.score ? time < other.time : score > other.score;
	}
	bool operator == (const People &other) const
	{
		return score == other.score && time == other.time;
	}
};
template <typename T>
struct Treap
{
	int root, tot;
	struct Node
	{
		int ls, rs, dat, cnt, siz;
		T val;
	}treap[N];
	void update(int p)
	{
		treap[p].siz = treap[treap[p].ls].siz + treap[treap[p].rs].siz + treap[p].cnt;
	}
	int create(T val)
	{
		treap[++tot].val = val;
		treap[tot].dat = rand();
		treap[tot].siz = treap[tot].cnt = 1;
		return tot;
	}
	void zig(int &p)
	{
		int q = treap[p].ls;
		treap[p].ls = treap[q].rs;
		treap[q].rs = p;
		p = q;
		update(treap[p].rs);
		update(p);
	}
	void zag(int &p)
	{
		int q = treap[p].rs;
		treap[p].rs = treap[q].ls;
		treap[q].ls = p;
		p = q;
		update(treap[p].ls);
		update(p);
	}
	void build()
	{
		tot = 0;
		root = create((T){INF});
		create((T){-INF});
		treap[1].rs = 2;
		update(root);
	}
	T get_val(int p, int rank)
	{
		if (!p)
		{
			return (T){-INF};
		}
		if (treap[treap[p].ls].siz >= rank)
		{
			return get_val(treap[p].ls, rank);
		}
		if (treap[treap[p].ls].siz + treap[p].cnt >= rank)
		{
			return treap[p].val;
		}
		return get_val(treap[p].rs, rank - treap[treap[p].ls].siz - treap[p].cnt);
	}
	int get_rank(int p, T val)
	{
		if (!p)
		{
			return 1;
		}
		if (val == treap[p].val)
		{
			return treap[treap[p].ls].siz + 1;
		}
		if (val < treap[p].val)
		{
			return get_rank(treap[p].ls, val);
		}
		return treap[treap[p].ls].siz + treap[p].cnt + get_rank(treap[p].rs, val);
	}
	void insert(int &p, T val)
	{
		if (!p)
		{
			p = create(val);
			return;
		}
		if (val == treap[p].val)
		{
			treap[p].cnt++;
		}
		else if (val < treap[p].val)
		{
			insert(treap[p].ls, val);
			if (treap[p].dat < treap[treap[p].ls].dat)
			{
				zig(p);
			}
		}
		else
		{
			insert(treap[p].rs, val);
			if (treap[p].dat < treap[treap[p].rs].dat)
			{
				zag(p);
			}
		}
		update(p);
	}
	void remove(int &p, T val)
	{
		if (!p)
		{
			return;
		}
		if (val == treap[p].val)
		{
			if (treap[p].cnt > 1)
			{
				treap[p].cnt--;
				update(p);
			}
			else if (treap[p].ls || treap[p].rs)
			{
				if (!treap[p].rs || treap[treap[p].ls].dat > treap[treap[p].rs].dat)
				{
					zig(p);
					remove(treap[p].rs, val);
				}
				else
				{
					zag(p);
					remove(treap[p].ls, val);
				}
				update(p);
			}
			else
			{
				p = 0;
			}
			return;
		}
		val < treap[p].val ? remove(treap[p].ls, val) : remove(treap[p].rs, val);
		update(p);
	}
};
map<string, pair<int, int>> mp;
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	Treap<People> t;
	t.build();
	char op;
	string name;
	int score, rank;
	for (int i = 1; i <= n; i++)
	{
		cin >> op >> name;
		if (op == '+')
		{
			cin >> score;
			if (mp[name].first)
			{
				t.remove(t.root, (People){mp[name].first, mp[name].second, name});
			}
			mp[name].first = score;
			mp[name].second = i;
			t.insert(t.root, (People){score, i, name});
		}
		else
		{
			if ('0' <= name[0] && name[0] <= '9')
			{
				rank = 0;
				for (int j = name.size() - 1; j >= 0; j--)
				{
					rank = (rank << 1) + (rank << 3) + (name[j] ^ 48);
				}
				for (int j = rank; j < rank + 10 && t.get_val(t.root, j + 1).score != -INF; j++)
				{
					cout << t.get_val(t.root, j + 1).name << ' ';
				}
			}
			else
			{
				cout << t.get_rank(t.root, (People){mp[name].first, mp[name].second}) - 1;
			}
			cout << '\n';
		}
	}
	return 0;
}

RT

2024/11/3 19:26
加载中...