平衡树板子求调,调了2h了,样例没过,悬两关
查看原帖
平衡树板子求调,调了2h了,样例没过,悬两关
708102
bijhla楼主2024/5/26 15:28
#include <bits/stdc++.h>
#define PII pair <int, int>
#define ll long long
#define MP make_pair
#define PB push_back
using namespace std;
constexpr int N = 1e5 + 10;
int n, cnt, root;
struct node
{
    int f, cnt, val, son[2], qua;
} spl[N];
inline bool get_which (int x) {return spl[spl[x].f].son[1] == x;}
inline void spl_clear (int x) {spl[x].son[0] = spl[x].son[1] = spl[x].f = spl[x].cnt = spl[x].qua = spl[x].val = 0;}
inline void update (int x)
{
    if (x)
    {
        spl[x].qua = spl[x].cnt;
        if (spl[x].son[0]) spl[x].qua += spl[spl[x].son[0]].qua;
        if (spl[x].son[0]) spl[x].qua += spl[spl[x].son[1]].qua;
    }
}
inline void rotate (int x)
{
    int fa = spl[x].f, gf = spl[fa].f, which_son = get_which (x);
    spl[fa].son[which_son] = spl[x].son[which_son ^ 1];
    spl[spl[x].son[which_son ^ 1]].f = fa;
    spl[x].son[which_son ^ 1] = fa;
    spl[x].f = gf;
    spl[fa].f = x;
    if (gf) spl[gf].son[get_which (fa)] = x;
    update (x);
    update (fa);
}
inline void splay (int x)
{
    for (int fa = spl[x].f; fa = spl[x].f, fa; rotate (x))
	{
        if (spl[fa].f) rotate (get_which (x) == get_which (fa) ? fa : x);
	}
	root = x;
}
inline void insert (int x)
{
    if (!root)
    {
        spl_clear (++cnt);
        root = cnt;
        spl[cnt].qua = spl[cnt].cnt++;
        spl[cnt].val = x;
		return;
    }
    int now = root, fa = 0;
    while (1)
    {
        if (x == spl[now].val)
        {
            spl[now].cnt++;
            update (now);
            update (fa);
			return;
        }
        fa = now;
        now = spl[now].son[x > spl[now].val];
        if (!now)
        {
            now = ++cnt;
            spl[now].f = fa;
            spl[now].qua = spl[now].cnt = 1;
            spl[fa].son[x > spl[fa].val] = now;
            spl[now].val = x;
            update (fa);
            splay (now);
            return;
        }
    }
}
inline int find_rank (int x)
{
    int k = 0, now = root;
    while (1)
    {
        if (x < spl[now].val) now = spl[now].son[0];
        else
        {
            if (spl[now].son[0]) k += spl[spl[now].son[0]].qua;
            if (x == spl[now].val) 
			{
				splay (now);
				return k + 1;
            }
			k += spl[now].cnt;
            now = spl[now].son[1];
        }
    }
}
inline int find_num (int x)
{
    int now = root;
    while (1)
    {
        if (spl[now].son[0] && spl[spl[now].son[0]].qua >= x) now = spl[now].son[0];
        else
        {
            int qua = (spl[now].son[0] ? spl[spl[now].son[0]].qua : 0) + spl[now].cnt;
            if (x <= qua) 
			{
				splay (now);
				return spl[now].val;
            }
			x -= qua;
            now = spl[now].son[1];
        }
    }
}
inline int find_pre ()
{
	int now = spl[root].son[0];
	if (!now) return now;
	while (spl[now].son[1]) now = spl[now].son[1];
	splay (now);
	return now;
}
inline int find_suffix ()
{
	int now = spl[root].son[1];
	if (!now) return now;
	while (spl[now].son[0]) now = spl[now].son[0];
	splay (now);
	return now;
}
inline void del (int x)
{
	int tmp = find_rank (x);
	if (spl[root].cnt > 1)
	{
		spl[root].cnt--;
		update (root);
	}
	else if (!spl[root].son[0] && !spl[root].son[1])
	{
		spl_clear (root);
		root = 0;
	}
	else if (!spl[root].son[0])
	{
		int old_root = root;
		root = spl[old_root].son[1];
		spl[root].f = 0;
		spl_clear (old_root);
	}
	else if (!spl[root].son[1])
	{
		int old_root = root;
		root = spl[old_root].son[0];
		spl[root].f = 0;
		spl_clear (old_root);
	}
	else
	{
		int old_root = root, now = find_pre ();
		spl[now].f = 0;
		spl[x].son[1] = spl[old_root].son[1];
		spl[spl[old_root].son[1]].f = now;
		spl_clear (old_root);
		update (now);
	}
}
int main()
{
    ios::sync_with_stdio (false);
    cin.tie (0);
    cout.tie (0);
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        int op, x;
        cin >> op >> x;
        if (op == 1) insert (x);
        else if (op == 2) del (x);
        else if (op == 3) cout << find_rank (x) << "\n";
        else if (op == 4) cout << find_num (x) << "\n";
        else if (op == 5) {insert (x), cout << find_pre () << "\n", del (x);}
        else {insert (x), cout << find_suffix () << "\n", del (x);}
    }
    return 0;
}

2024/5/26 15:28
加载中...