有旋 Treap WA on #1#2 求调
查看原帖
有旋 Treap WA on #1#2 求调
255169
__LePetitPrince__楼主2023/12/12 23:31

对着 LYD 蓝书抄的,应该是一样的,求大佬帮忙看看 Orz

#include <iostream>
#include <stdio.h>
using namespace std;
const int S = 1e5 + 5;
const int I = 1 << 30;

struct N {
	int l, r;
	int val, lev;
	int cnt, siz;
} a[S];
int tot, root, q;

int newnode(int val) {
	a[++tot].val = val;
	a[tot].lev = rand();
	a[tot].cnt = a[tot].siz = 1;
	return tot;
}

void pushup(int p) {
	a[p].siz = a[a[p].l].siz + a[a[p].r].siz + a[p].cnt;
}

void build() {
	newnode(-I);
	newnode(I);
	root = 1;
	a[1].r = 2;
	pushup(root);
}

int getRankByVal(int p, int val) {
	if (p == 0) {
		return 0;
	}
	if (val == a[p].val) {
		return a[a[p].l].siz + 1;
	}
	if (val < a[p].val) {
		return getRankByVal(a[p].l, val);
	}
	return getRankByVal(a[p].r, val) + a[a[p].l].siz + a[p].cnt;
}

int getValByRank(int p, int rank) {
	if (p == 0) {
		return I;
	}
	if (a[a[p].l].siz >= rank) {
		return getValByRank(a[p].l, rank);
	}
	if (a[a[p].l].siz + a[p].cnt >= rank) {
		return a[p].val;
	}
	return getValByRank(a[p].r, rank - a[a[p].l].siz - a[p].cnt);
}

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

void zag(int &p) {
	int q = a[p].r;
	a[p].r = a[q].l, a[q].l = p, p = q;
	pushup(a[p].l);
	pushup(p);
}

void insert(int &p, int val) {
	if (p == 0) {
		p = newnode(val);
		return;
	}
	if (val == a[p].val) {
		a[p].cnt++;
		pushup(p);
		return;
	}
	if (val < a[p].val) {
		insert(a[p].l, val);
		if (a[p].lev < a[a[p].l].lev) {
			zig(p);
		}
	} else {
		insert(a[p].r, val);
		if (a[p].lev < a[a[p].r].lev) {
			zag(p);
		}
	}
	pushup(p);
}

int getPre(int val) {
	int ans = 1; // a[1].val == -I
	int p = root;
	while (p) {
		if (val == a[p].val) {
			if (a[p].l > 0) {
				p = a[p].l;
				while (a[p].r > 0) {
					p = a[p].r;
				}
				ans = p;
			}
			break;
		}
		if (a[p].val < val && a[p].val > a[ans].val) {
			ans = p;
		}
		if (val < a[p].val) {
			p = a[p].l;
		} else {
			p = a[p].r;
		}
	}
	return a[ans].val;
}

int getNext(int val) {
	int ans = 2; // a[2].val == I
	int p = root;
	while (p) {
		if (val == a[p].val) {
			if (a[p].r > 0) {
				p = a[p].r;
				while (a[p].l > 0) {
					p = a[p].l;
				}
				ans = p;
			}
			break;
		}
		if (a[p].val > val && a[p].val < a[ans].val) {
			ans = p;
		}
		if (val < a[p].val) {
			p = a[p].l;
		} else {
			p = a[p].r;
		}
	}
	return a[ans].val;
}

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

int main() {
	build();
	cin >> q;
	while (q--) {
		int op, x;
		scanf("%d%d", &op, &x);
		switch (op) {
			case 1: {
				insert(root, x);
				break;
			}
			case 2: {
				remove(root, x);
				break;
			}
			case 3: {
				printf("%d\n", getRankByVal(root, x) - 1);
				break;
			}
			case 4: {
				printf("%d\n", getValByRank(root, x + 1));
				break;
			}
			case 5: {
				printf("%d\n", getPre(x));
				break;
			}
			case 6: {
				printf("%d\n", getNext(x));
				break;
			}
		}
	}
	return 0;
} 
2023/12/12 23:31
加载中...