萌新 Splay 求条
查看原帖
萌新 Splay 求条
882092
zMinYu楼主2024/3/25 22:04
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7, INF = 1e8;
struct Splay {
	int s[2], v, p, cnt, siz;
};

Splay tr[N];
int n, root = 0, idx = 0, opt, X;

void pushup(int u) {
	tr[u].siz = tr[tr[u].s[0]].siz + tr[tr[u].s[1]].siz + tr[u].cnt;
}

int Get(int x) {
	return tr[tr[x].p].s[1] == x;
}

void rotate(int x) {
	int y = tr[x].p, z = tr[y].p;
	int kx = Get(x), ky = Get(y);
	tr[z].s[ky] = x;
	tr[x].p = z;
	tr[y].s[kx] = tr[x].s[kx ^ 1];
	tr[tr[x].s[kx ^ 1]].p = y;
	tr[x].s[kx ^ 1] = y;
	tr[y].p = x;
	pushup(y), pushup(x);
	return;
}

void splay(int x, int k) {
	while (tr[x].p != k) {
		int y = tr[x].p, z = tr[y].p;
		if (z != k) {
			if (Get(x) == Get(y)) rotate(y);
			else rotate(x);
		}
		rotate(x);
	}
	if(!k) root = x;
	return;
}

void insert(int v) {
	int u = root, p = 0;
	while (u) {
		if (tr[u].v == v) {
			tr[u].cnt++;
			splay(u, 0);
			return;
		}
		p = u;
		u = tr[u].s[v > tr[u].v];
	}
	u = ++idx;
	if (p) tr[p].s[v > tr[p].v] = u;
	tr[u].p = p;
	tr[u].v = v;
	tr[u].siz = 1;
	splay(u, 0);
	return;
}

void find(int x) {
	if (!root) return;
	int u = root;
	while (tr[u].s[x > tr[u].v] && tr[u].v != x) u = tr[u].s[x > tr[u].v];
	splay(u, 0);
	return;
}

int Last(int x) {
	find(x);
	if (tr[root].v < x) return root;
	int u = tr[root].s[0];
	while (tr[u].s[1]) u = tr[u].s[1];
	splay(u, 0);
	return u;
}

int Next(int x) {
	find(x);
	if (tr[root].v > x) return root;
	int u = tr[root].s[1];
	while (tr[u].s[0]) u = tr[u].s[0];
	splay(u, 0);
	return u;
}

void Delete(int x) {
	int L = Last(x), N = Next(x);
	splay(L, 0), splay(N, L);
	int d = tr[N].s[0];
	if (tr[d].cnt > 1) tr[d].cnt--, splay(d, 0);
	else tr[N].s[0] = 0;
	pushup(N), pushup(L);
	return;
}

int get_rank(int x) {
	find(x);
	if (tr[root].v < x) return tr[root].cnt + tr[tr[root].s[0]].siz;
	return tr[tr[root].s[0]].siz;
}

int Kth(int k) {
	int u = root;
	while (1) {
//		cout << 1 << ' ';
		if (k <= tr[tr[u].s[0]].siz && tr[u].s[0]) 
			u = tr[u].s[0];
		else if (k > tr[tr[u].s[0]].siz + tr[u].cnt) {
			k -= tr[tr[u].s[0]].siz + tr[u].cnt, u = tr[u].s[1];
//			cout << tr[u].cnt;
		}
		else {
//			cout << 1;
			splay(u, 0);
			return u;
		}
	}
	return 114514;
}

int main() {
	insert(INF), insert(-INF);
	cin >> n;
	while (n--) {
		cin >> opt >> X;
		if (opt == 1) insert(X);
		else if (opt == 2) Delete(X);
		else if (opt == 3) cout << get_rank(X) << '\n';
		else if (opt == 4) cout << tr[Kth(X + 1)].v << '\n';
		else if (opt == 5) cout << tr[Last(X)].v << '\n';
		else cout << tr[Next(X)].v << '\n';
	}
	return 0;
}

Kth 操作总是出不来,不知道为啥。

2024/3/25 22:04
加载中...