FHQ_Treap 求条
查看原帖
FHQ_Treap 求条
730195
Little_Cabbage楼主2024/3/1 16:24

7pts

#include <bits/stdc++.h>
#define ull unsigned long long
#define int long long
#define ldb long double
#define db double
#define endl '\n'
using namespace std;
int read() {
	char c = 0;
	int f = 1, x = 0;
	while (c < '0' || c > '9') {
		if (c == '-')
			f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		x = x * 10 + (int)(c - '0');
		c = getchar();
	}
	return f * x;
}
void write(int x) {
	if (x == 0) {
		putchar(x + '0');
		return ;
	}
	if (x < 0) {
		putchar('-');
		x = abs(x);
	}
	stack<int> s;
	while (x) {
		s.push(x % 10);
		x /= 10;
	}
	while (s.size()) {
		putchar(s.top() + '0');
		s.pop();
	}
}
const int N = 200010;
#define ls(k) FHQ_Treap[k].left_son
#define rs(k) FHQ_Treap[k].right_son
#define va(k) FHQ_Treap[k].val
#define cn(k) FHQ_Treap[k].cnt
#define fa(k) FHQ_Treap[k].father
#define pri(k) FHQ_Treap[k].priority
#define lss(k) FHQ_Treap[k].left_son_sum
#define rss(k) FHQ_Treap[k].right_son_sum
struct FHQ_Treap_ {
	int left_son, right_son;
	int val, cnt;
	int father;
	int priority;
	int left_son_sum, right_son_sum;
} FHQ_Treap[N];
int root;
int n, root1, root2, ans, a[N];
int tot;
int New_FHQ_Treap(int x) {
	tot++;
	ls(tot) = rs(tot) = lss(tot) = rss(tot) = fa(tot) = 0;
	va(tot) = x;
	pri(tot) = rand();
	cn(tot) = 1;
	return tot;
}
void Pushup(int x) {
	if (ls(x))
		lss(x) = lss(ls(x)) + rss(ls(x)) + 1 + cn(ls(x));
	else
		lss(x) = 0;
	if (rs(x))
		rss(x) = lss(rs(x)) + rss(rs(x)) + 1 + cn(rs(x));
	else
		rss(x) = 0;
}
void Split_value(int id, int key, int &lroot, int &rroor) {
	if (!id) {
		lroot = rroor = 0;
		return ;
	}
	if (va(id) <= key) {
		lroot = id;
		Split_value(rs(lroot), key, rs(lroot), rroor);
	} else {
		rroor = id;
		Split_value(ls(rroor), key, lroot, ls(rroor));
	}
	Pushup(id);
}
void Split_rank() {
	;
}
int Merge(int lroot, int rroot) {
	if (!lroot || !rroot) return lroot | rroot;
	if (pri(lroot) <= pri(rroot)) {
		rs(lroot) = Merge(rs(lroot), rroot);
		Pushup(lroot);
		return lroot;
	} else {
		ls(rroot) = Merge(lroot, ls(rroot));
		Pushup(rroot);
		return rroot;
	}
}
int Find(int x) {
	int y = root;
	while (y) {
		if (va(y) == x) return y;
		if (x <= va(y)) y = ls(y);
		else y = rs(y);
	}
	return -1;
}
void Insert(int x) {
	int t = Find(x);
	if (t != -1) {
		cn(t)++;
		return ;
	}
	root1 = root2 = 0;
	Split_value(root, x - 1, root1, root2);
//	cout << "yes";
	root = Merge(Merge(root1, New_FHQ_Treap(x)), root2);
//	cout << "yes";
}
void Delete(int x) {
	int tmp;
	Split_value(root, x - 1, root1, root2);
	Split_value(root2, x, tmp, root2);
	tmp = Merge(ls(tmp), rs(tmp));
	root = Merge(root1, Merge(tmp, root2));
}
int Query_x_rank(int x) {
	Split_value(root, x - 1, root1, root2);
	int _rank = lss(root1) + rss(root1) + 1;
	root = Merge(root1, root2);
	return _rank;
}
int Query_rank_x(int id, int x) {
	int t = lss(id) + rss(id) + 1;
	if (t == x) return va(id);
	if (x < t) return Query_rank_x(ls(id), x);
	else return Query_rank_x(rs(id), x - t);
}
int Pred(int x) {
	Split_value(root, x, root1, root2);
	int y = root1;
	while (y) {
		if (rs(y) == 0) break;
		y = rs(y);
	}
	root = Merge(root1, root2);
	if (y) return va(y);
	return -1;
}
int Succ(int x) {
	Split_value(root, x - 1, root1, root2);
	int y = root2;
	while (y) {
		if (ls(y) == 0) break;
		y = ls(y);
	}
	root = Merge(root1, root2);
	if (y) return va(y);
	return -1;
}
signed main() {
//	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
//	freopen("P3369_7.in", "r", stdin);
//	freopen("P3369_7.out", "w", stdout);
	srand(time(NULL));
	n = read();
	while (n--) {
		int opt, x;
		opt = read(), x = read();
		switch (opt) {
			case 1:
				Insert(x);
				break;
			case 2: {
				int t = Find(x);
				if (t != -1)
					cn(t)--;
				Delete(x);
				break;
			}
			case 3:{
				bool flag = false;
				int t = Find(x);
				if (t == -1) {
					Insert(x);
					flag = true;
				}
				cout << Query_x_rank(x) << endl;
				if (flag) Delete(x);
				break;
			}
			case 4:
				cout << Query_rank_x(root, x) << endl;
				break;
			case 5:{
				bool flag = false;
				int t = Find(x);
				if (t == -1) {
					Insert(x);
					flag = true;
				}
				cout << Pred(x) << endl;
				if (flag) Delete(x);
				break;
			}
			case 6: {
				bool flag = false;
				int t = Find(x);
				if (t == -1) {
					Insert(x);
					flag = true;
				}
				cout << Succ(x) << endl;
				if (flag) Delete(x);
				break;
			}
		}
	}
	return 0;
}

2024/3/1 16:24
加载中...