treap 求调过最后两个点
查看原帖
treap 求调过最后两个点
799877
AK_heaven楼主2024/3/9 19:49
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 10;

map<int, int> mp;

struct Tree {
	int l, r;
	int val, dat;
	int cnt, size;
}tr[maxn];

int tot, root, n;

int New(int val) {
	tr[++tot].size = tr[tot].cnt = 1;
	tr[tot].val = val;
	tr[tot].dat = rand();
	return tot;
}

void update(int p) {
	tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + tr[p].cnt;
}

void build() {
	New(-1e9); New(1e9);
	tr[1].r = 2;
	root = 1;
	update(1);
}

int q1(int p, int val) {
	if(p == 0) return 1; // 如果没有则返回0
	if(val == tr[p].val) return tr[tr[p].l].size + 1;
	if(val < tr[p].val) return q1(tr[p].l, val);
	return q1(tr[p].r, val) + tr[tr[p].l].size + tr[p].cnt;
}

int q2(int p, int rank) {
	if(p == 0) return 1e9;
	if(tr[tr[p].l].size >= rank) return q2(tr[p].l, rank);
	if(tr[tr[p].l].size + tr[p].cnt >= rank) return tr[p].val;
	return q2(tr[p].r, rank - tr[tr[p].l].size - tr[p].cnt);
}

void zig(int &p) {
	int q = tr[p].l;
	tr[p].l = tr[q].r, tr[q].r = p, p = q;
	update(tr[p].r); update(p);
}

void zag(int &p) {
	int q = tr[p].r;
	tr[p].r = tr[q].l, tr[q].l = p, p = q; // 先继承 
	update(tr[p].l); update(p);
}

void insert(int &p, int val) {
	if(p == 0) {
		p = New(val);
		return ;
	}
	if(val == tr[p].val) {
		tr[p].cnt++;
		update(p);
		return ;
	}
	if(val < tr[p].val) {
		insert(tr[p].l, val);
		if(tr[p].dat < tr[tr[p].l].dat) zig(p);
	}
	else {
		insert(tr[p].r, val);
		if(tr[p].dat < tr[tr[p].r].dat) zag(p);
	}
	update(p);
} 

int getpre(int val) {
	int ans = 1;
	int p = root;
	while(p) {
		if(val == tr[p].val) {
			if(tr[p].l > 0) {
				p = tr[p].l;
				while(tr[p].r > 0) p = tr[p].r;
				ans = p;
			}
			break;
		}
		if(tr[p].val < val && tr[p].val > tr[ans].val) ans = p;
		p = ((val < tr[p].val) ? tr[p].l : tr[p].r);
	}
	return ans;
}

int getnxt(int val) {
	int ans = 2;
	int p = root;
	while(p) {
		if(val == tr[p].val) {
			if(tr[p].r > 0) {
				p = tr[p].r;
				while(tr[p].l > 0) p = tr[p].l;
				ans = p;
			}
			break;
		}
		if(tr[p].val > val && tr[p].val < tr[ans].val) ans = p;
		p = ((val < tr[p].val) ? tr[p].l : tr[p].r);
	}
	return ans;
}

void remove(int &p, int val) {
	if(p == 0) return ;
	if(val == tr[p].val) {
		if(tr[p].cnt > 1) {
			tr[p].cnt--;
			update(p);
			return ;
		}
		if(tr[p].l || tr[p].r) {
			if(tr[p].r == 0 || tr[tr[p].l].dat > tr[tr[p].r].dat)
			  zig(p), remove(tr[p].r, val);
			else 
			  zag(p), remove(tr[p].l, val);
			update(p);
		}
		else p = 0;
		return ;
	}
	else if(val < tr[p].val)
	  remove(tr[p].l, val);
	else {
		remove(tr[p].r, val);
	}
	update(p);
}

int main() {
	build();
	cin >> n;
	while(n--) {
		int op, x;
		cin >> op >> x;
		if(op == 1) insert(root, x);
		if(op == 2) remove(root, x);
		if(op == 3) cout << q1(root, x)-1 << '\n';
		if(op == 4) cout << q2(root, x+1) << '\n';
		if(op == 5) cout << tr[getpre(x)].val << '\n';
		if(op == 6) cout << tr[getnxt(x)].val << '\n';
	}
	return 0;
}
2024/3/9 19:49
加载中...