splay模板

Splay模板
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int MAX_N = 1e5 + 10;
const int inf = 0x3f3f3f3f;
struct node {
	int f, cnt, ch[2], val, size;
}tr[MAX_N];
int root = 0;
int tot = 0;
int n;
void push_up(int p) {
	tr[p].size = tr[tr[p].ch[0]].size + tr[tr[p].ch[1]].size + tr[p].cnt;
}
void rotate(int x) {
	int y = tr[x].f;
	int z = tr[y].f;
	int k = tr[y].ch[1] == x;
	tr[z].ch[tr[z].ch[1] == y] = x;
	tr[x].f = z;
	tr[y].ch[k] = tr[x].ch[k ^ 1];
	tr[tr[x].ch[k ^ 1]].f = y;
	tr[x].ch[k ^ 1] = y;
	tr[y].f = x;
	push_up(x), push_up(y);
}

void splay(int x, int goal) {
	while (tr[x].f != goal) {
		int y = tr[x].f, z = tr[y].f;
		if (z != goal) {
			(tr[z].ch[0] == y) ^ (tr[y].ch[0] == x) ? rotate(x) : rotate(y);
		}
		rotate(x);
	}
	if (goal == 0)root = x;
}

inline void find_(int x) {
	int u = root;
	if (!u)return;
	while (tr[u].ch[x > tr[u].val] && x != tr[u].val)
		u = tr[u].ch[x > tr[u].val];
	splay(u, 0);
}

inline void insert(int x) {
	int u = root, ff = 0;
	while (u && tr[u].val != x) {
		ff = u;
		u = tr[u].ch[x > tr[u].val];
	}
	if (u)tr[u].cnt++;
	else {
		u = ++tot;
		if (ff) {
			tr[ff].ch[x > tr[ff].val] = u;
		}
		tr[u].ch[0] = tr[u].ch[1] = 0;
		tr[u].f = ff;
		tr[u].val = x;
		tr[u].size = tr[u].cnt = 1;
	}
	splay(u, 0);
}

inline int get_next(int x, int f) {
	find_(x);
	int u = root;
	if (tr[u].val > x&& f)return u;
	else if (tr[u].val < x && !f)return u;
	u = tr[u].ch[f];
	while (tr[u].ch[f ^ 1])u = tr[u].ch[f ^ 1];
	return u;
}
inline void Delete(int x) {
	int last = get_next(x, 0);
	int Next = get_next(x, 1);
	splay(last, 0), splay(Next, last);
	int del = tr[Next].ch[0];
	if (tr[del].cnt > 1) {
		tr[del].cnt--;
		splay(del, 0);
	}
	else{
		tr[Next].ch[0] = 0;
	}
}
inline int kth(int x) {
	int u = root;
	if (tr[u].size < x)return 0;
	while (1) {
		if (tr[u].cnt + tr[tr[u].ch[0]].size < x) {
			x = x - tr[tr[u].ch[0]].size - tr[u].cnt;
			u = tr[u].ch[1];
		}
		else {
			if (tr[tr[u].ch[0]].size >= x)u = tr[u].ch[0];
			else
				return tr[u].val;
		}
	}
}
int main() {
	int n;
	scanf("%d", &n);
	insert(1e9);
	insert(-1e9);
	while (n--)
	{
		int opt, x;
		scanf("%d%d", &opt, &x);
		if (opt == 1)
			insert(x);
		if (opt == 2)
			Delete(x);
		if (opt == 3)
		{
			find_(x);
			printf("%d\n", tr[tr[root].ch[0]].size);
		}
		if (opt == 4)
			printf("%d\n", kth(x + 1));
		if (opt == 5)
			printf("%d\n", tr[get_next(x, 0)].val);
		if (opt == 6)
			printf("%d\n", tr[get_next(x, 1)].val);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值