灵异现象
  • 板块灌水区
  • 楼主zhx20081129
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/7/20 12:06
  • 上次更新2024/7/20 13:57:39
查看原帖
灵异现象
914572
zhx20081129楼主2024/7/20 12:06

不开O2,RE on 3,5,6 ,7,8,9,10,11,12

开O2,MLE on 3,5,6 ,7,8,9,10,11,12

#include<bits/stdc++.h>
using namespace std;
//FHQ Treap
const int N = 1e5 + 10;
//树节点的定义
struct treeNode {
	int key/*键值*/, pri/*优先级*/;
	int ls, rs;/*左右孩子*/
	int size;/*以当前节点为根的子树中的节点的数量,用于排名、第k大*/
}t[N];
int cnt/*新建节点的编号*/, root/*根节点*/;
//根据键值x创建一个新的树节点
void newNode(int x) {
	t[++cnt].key = x, t[cnt].pri = rand();
	t[cnt].ls = t[cnt].rs = 0;
	t[cnt].size = 1;
}
//更新节点编号为u的size
void update(int u) {
	t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
}

//两大核心/基本操作-分裂与合并
//分裂-权值分裂-时间复杂度-O(logn)
//对于当前树u,将树u中键值小于等于x的都放到左树L,大于x的都放到右树R
void Split(int u/*当前树的树根*/, int x/*键值*/, int& L, int& R) {
	if (u == 0) { L = R = 0; return; }
	if (t[u].key <= x) {
		L = u;
		Split(t[u].rs, x, t[u].rs, R);
	}
	else {
		R = u;
		Split(t[u].ls, x, L, t[u].ls);
	}
	update(u);
}
//合并-时间复杂度-O(logn)
int Merge(int L, int R) {
	if (L == 0 || R == 0) return L + R;
	if (t[L].pri > t[R].pri) {
		t[L].rs = Merge(t[L].rs,R);
		update(L);
		return L;
	}
	else {
		t[R].ls = Merge(L, t[R].ls);
		update(R); 
		return R;
	}
}
//六大基本操作
//1.插入
void insert(int x/*键值*/) {
	int L, R;
	Split(root, x, L, R);
	newNode(x);
	root = Merge(Merge(L, cnt), R);
}
//2.删除
void del(int x/*键值*/) {
	int L, R, p;
	Split(root, x, L, R);
	Split(L, x - 1, L, p);
	p = Merge(t[p].ls, t[p].rs);
	root=Merge(Merge(L, p), R);
}
//3.排名
void Rank(int x/*键值*/) {
	int L, R;
	Split(root, x - 1, L, R);
	printf("%d\n", t[L].size + 1);
	root = Merge(L, R);

}
//4.第k大
int kth(int u,int k) {
	if (k == t[t[u].ls].size + 1) return u;
	else if (k > t[t[u].ls].size) return kth(t[u].rs, k - (t[t[u].ls].size + 1));
	else kth(t[u].ls, k);
}
//5.前驱
void precursor(int x/*键值*/) {
	int L, R;
	Split(root, x - 1, L, R);
	printf("%d\n", t[kth(L, t[L].size)].key);
	root=Merge(L, R);
}
//6.后继
void successor(int x/*键值*/) {
	int L, R;
	Split(root, x, L, R);
	printf("%d\n", t[kth(R, 1)].key);
	root = Merge(L, R);
}
int main() {
	srand(time(0));
	int n;  cin >> n;
	while (n--) {
		int opt, x;
		cin >> opt >> x;
		switch (opt) {
			case 1:insert(x); break;
			case 2:del(x); break;
			case 3:Rank(x); break;
			case 4:printf("%d\n",t[kth(root,x)].key); break;
			case 5:precursor(x); break;
			case 6:successor(x); break;

		}
	}
	return 0;
}
2024/7/20 12:06
加载中...