可持久化fhq treap求助,只过了最后五个点和第二个点
查看原帖
可持久化fhq treap求助,只过了最后五个点和第二个点
291939
lihuazou楼主2021/5/27 20:28
#include <iostream>
#include <algorithm>

#define inf 0x7FFFFFFF

const int N = 2e7 + 100;
const int M = 1e6 + 10;

int cnt, root[M], tot, x, y, z;

struct node {
	int lc, rc, sz, key, val;
	node() { lc = rc = sz = key = val = 0; }
	node(int val) { lc = rc = 0; sz = 1; key = std::rand(); this->val = val; }
}treap[N];

inline int getLc(int rt) { return treap[rt].lc; }

inline int getRc(int rt) { return treap[rt].rc; }

inline void pushup(int rt) { treap[rt].sz = treap[getLc(rt)].sz + treap[getRc(rt)].sz + 1; }

inline void split(int rt, int sign, int& x, int& y) {
	if (!rt) { x = y = 0; return; }
	treap[++cnt] = treap[rt];
	int id = cnt;
	if (treap[rt].val <= sign) {
		x = id;
		split(treap[rt].rc, sign, treap[x].rc, y);
	}
	else {
		y = id;
		split(treap[rt].lc, sign, x, treap[y].lc);
	}
	pushup(id);
}

inline int marge(int x, int y) {
	if (!x || !y) return x + y;
	int id = ++cnt;
	if (treap[x].key < treap[y].key) {
		treap[id] = treap[x];
		treap[id].rc = marge(treap[id].rc, y);
	}
	else {
		treap[id] = treap[y];
		treap[id].lc = marge(x, treap[id].lc);
	}
	pushup(id);
	return id;
}

inline void op_insert(int id, int val) {
	treap[++cnt] = node(val);
	int ins = cnt;
	root[++tot] = root[id];
	split(root[tot], val, x, y);
	root[tot] = marge(marge(x, ins), y);
}

inline void op_delete(int id, int val) {
	root[++tot] = root[id];
	split(root[tot], val, x, y);
	split(x, val - 1, x, z);
	if (treap[z].sz > 1) x = marge(x, marge(treap[z].lc, treap[z].rc));
	root[tot] = marge(x, y);
}

inline void getRank(int id, int val) {
	root[++tot] = root[id];
	split(root[tot], val - 1, x, y);
	std::cout << treap[x].sz + 1 << std::endl;
	root[tot] = marge(x, y);
}

inline void getKth(int id, int kth) {
	root[++tot] = root[id];
	int rt = root[tot];
	if (kth > treap[rt].sz) {
		std::cout << inf << std::endl;
		return;
	}
	while (true) {
		if (treap[getLc(rt)].sz + 1 == kth) { std::cout << treap[rt].val << std::endl; return; }
		else if (treap[getLc(rt)].sz >= kth) rt = getLc(rt);
		else { kth = kth - 1 - treap[getLc(rt)].sz; rt = getRc(rt); }
	}
}

inline void getPrev(int id, int val) {
	root[++tot] = root[id];
	split(root[tot], val - 1, x, y);
	if (treap[x].sz == 0) {
		std::cout << -inf << std::endl;
		root[tot] = marge(x, y);
	}
	else {
		int kth = treap[x].sz;
		root[tot] = marge(x, y);
		getKth(id, kth);
	}
}

inline void getNext(int id, int val) {
	root[++tot] = root[id];
	split(root[tot], val, x, y);
	if (treap[y].sz == 0) {
		std::cout << inf << std::endl;
		root[tot] = marge(x, y);
	}
	else {
		int kth = treap[x].sz + 1;
		root[tot] = marge(x, y);
		getKth(id, kth);
	}
}

signed main() {
	int id, op, val, n;
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	std::cin >> n;
	while (n--) {
		std::cin >> id >> op >> val;
		if (op == 1) op_insert(id, val);
		else if (op == 2) op_delete(id, val);
		else if (op == 3) getRank(id, val);
		else if (op == 4) getKth(id, val);
		else if (op == 5) getPrev(id, val);
		else getNext(id, val);
	}
}
2021/5/27 20:28
加载中...