FHQ-Treap MLE on #5-12 求调
查看原帖
FHQ-Treap MLE on #5-12 求调
378418
Chenaknoip楼主2025/1/27 22:17
#include <bits/stdc++.h>
using namespace std;
struct node {
	int ch[2];
	int val, pri;
	int cnt;
	int siz;
} fhq[100010];
int tot = 0;
node create(int x) {
	node res;
	res.ch[0] = res.ch[1] = 0;
	res.val = x;
	res.pri = rand();
	res.cnt = res.siz = 1;
	return res;
}
void pushup(int x) {
	fhq[x].siz = fhq[x].cnt;
	if (fhq[x].ch[0]) fhq[x].siz += fhq[fhq[x].ch[0]].siz;
	if (fhq[x].ch[1]) fhq[x].siz += fhq[fhq[x].ch[1]].siz;
}
int rt;
pair<int, int> split(int cur, int k) {
	if (cur == 0) return make_pair(0, 0);
	if (fhq[cur].val <= k) {
		pair<int, int> tmp = split(fhq[cur].ch[1], k);
		fhq[cur].ch[1] = tmp.first;
		pushup(cur);
		return make_pair(cur, tmp.second);
	} else {
		pair<int, int> tmp = split(fhq[cur].ch[0], k);
		fhq[cur].ch[0] = tmp.second;
		pushup(cur);
		return make_pair(tmp.first, cur);
	}
}
tuple<int, int, int> split2(int cur, int rk) { // split by rank
	if (!cur) return {0, 0, 0};
	int lsiz = !fhq[cur].ch[0] ? 0 : fhq[fhq[cur].ch[0]].siz;
	if (rk <= lsiz) {
		int l, mid, r;
		tie(l, mid, r) = split2(fhq[cur].ch[0], rk);
		pushup(cur);
		return {l, mid, cur};
	} else if (rk <= lsiz + fhq[cur].cnt) {
		int lt = fhq[cur].ch[0];
		int rt = fhq[cur].ch[1];
		fhq[cur].ch[0] = fhq[cur].ch[1] = 0;
		return {lt, cur, rt};
	} else {
		int l, mid, r;
		tie(l, mid, r) = split2(fhq[cur].ch[1], rk - lsiz - fhq[cur].cnt);
		fhq[cur].ch[1] = l;
		pushup(cur);
		return {cur, mid, r};
	}
}
int merge(int u, int v) {
	if (!u && !v) return 0;
	if (u && !v) return u;
	if (!u && v) return v;
	if (fhq[u].pri < fhq[v].pri) {
		fhq[u].ch[1] = merge(fhq[u].ch[1], v);
		pushup(u);
		return u;
	} else {
		fhq[v].ch[0] = merge(u, fhq[v].ch[0]);
		pushup(v);
		return v;
	}
}
void insert(int val) {
	pair<int, int> tmp = split(rt, val);
	pair<int, int> lt = split(tmp.first, val - 1);
	int newer;
	if (!lt.second) {
		newer = ++tot;
		fhq[newer] = create(val);
	} else {
		fhq[lt.second].cnt++;
		pushup(lt.second);
	}
	int ltc = merge(lt.first, !lt.second ? newer : lt.second);
	rt = merge(ltc, tmp.second);
}
void del(int val) {
	pair<int, int> tmp = split(rt, val);
	pair<int, int> lt = split(tmp.first, val - 1);
	if (fhq[lt.second].cnt > 1) {
		fhq[lt.second].cnt--;
		pushup(lt.second);
		lt.first = merge(lt.first, lt.second);
	} else {
		if (tmp.first == lt.second) {
			tmp.first = 0;
		}
		lt.second = 0;
	}
	rt = merge(lt.first, tmp.second);
}
int qrank(int cur, int val) { // find by val
	pair<int, int> tmp = split(cur, val - 1);
	int ret = (!tmp.first ? 0 : fhq[tmp.first].siz) + 1;
	rt = merge(tmp.first, tmp.second);
	return ret;
}
int qval(int cur, int rk) { // find by rank
	int l, mid, r;
	tie(l, mid, r) = split2(cur, rk);
	int ret = fhq[mid].val;
	rt = merge(merge(l, mid), r);
	return ret;
}
int qpre(int val) {
	pair<int, int> tmp = split(rt, val - 1);
	int ret = qval(tmp.first, fhq[tmp.first].siz);
	rt = merge(tmp.first, tmp.second);
	return ret;
}
int qnex(int val) {
	pair<int, int> tmp = split(rt, val);
	int ret = qval(tmp.second, 1);
	rt = merge(tmp.first, tmp.second);
	return ret;
}
int main() {
	srand(time(NULL));
	int t;
	scanf("%d", &t);
	while (t--) {
		int op, num;
		scanf("%d%d", &op, &num);
		if (op == 1) {
			insert(num);
		} else if (op == 2) {
			del(num);
		} else if (op == 3) {
			printf("%d\n", qrank(rt, num));
		} else if (op == 4) {
			printf("%d\n", qval(rt, num));
		} else if (op == 5) {
			printf("%d\n", qpre(num));
		} else {
			printf("%d\n", qnex(num));
		}
	}
	return 0;
}

2025/1/27 22:17
加载中...