P3369 【模板】普通平衡树 FHQ-treap求改
  • 板块学术版
  • 楼主Xx0okoukio0xX
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/8/9 16:15
  • 上次更新2024/8/9 16:57:07
查看原帖
P3369 【模板】普通平衡树 FHQ-treap求改
487843
Xx0okoukio0xX楼主2024/8/9 16:15

题目传送门

使用了FHQ-treap 100分的是旋转treap

有误代码如下:

#include<bits/stdc++.h>
using namespace std;

const int Tree_Size_Max = 1e5 + 10;


struct TREE{
	int siz;
	TREE* left;
	TREE* right;
	int val;
	int ran;
	
	// TREE operator=(const TREE *tp){
	// 	siz = tp -> siz;
	// 	left = tp -> left;
	// 	right = tp -> right;
	// 	val = tp -> val;
	// 	count = tp -> count;
	// }
	// TREE(){}
	TREE(int val):
		siz(1),left(nullptr),right(nullptr),val(val),ran(rand()){}
};

TREE* root = nullptr;
// TREE tree[Tree_Size_Max];

void upd_siz(TREE *x){
	if (!x) return;
	x->siz = 1;
	x->siz +=  x -> left ? x-> left -> siz : 0;
	x->siz +=  x-> right ? x -> right -> siz : 0;
}

// TREE* new_TREE(int x){
// 	sz++;
// //	tree[sz].count = 1;
// 	tree[sz].left = nullptr;
// 	tree[sz].right = nullptr;
// 	tree[sz].ran = rand();
// 	tree[sz].siz = 1;
// 	tree[sz].val = x;
// 	return &tree[sz];
// }

void split(TREE* &now, int k, TREE* &x, TREE* &y){
	if(now == nullptr){
		x = y = nullptr;
		return;
	}
	if(now -> val <= k){
		x = now;
		split(now -> right, k, x -> right, y);
		upd_siz(x);
	}else{
		y = now;
		split(now -> left , k, x, y -> left );
		upd_siz(y);
	}
}

TREE* merge(TREE *x, TREE *y){
	// if(x == nullptr && y == nullptr) return nullptr;
	if(x == nullptr) return y;
	if(y == nullptr) return x;
	
	
	if(x -> ran > y -> ran){
		x -> right = merge(x -> right, y);
		upd_siz(x);
		return x; 
	}
	else{
		y -> left = merge(x, y -> left);
		upd_siz(y);
		return y;
	}
}

void preOrder(TREE* rt){
	if(!rt) return;
	printf("%d ",rt -> val);
	preOrder(rt -> left);
	preOrder(rt ->  right);
}

void inOrder(TREE* rt){
	if(!rt) return;
	inOrder(rt -> left);
	printf("%d ",rt -> val);
	inOrder(rt -> right);
}

void insert(int x){
	TREE *a;
	TREE *b;
	TREE* NewTree = new TREE(x);
	split(root, x, a, b);
	root = merge(merge(a, NewTree) , b);
	
	
//	preOrder(root),printf("\n");
//	inOrder(root),printf("\n");
}

void del(int x){
	TREE* a;
	TREE* b;
	TREE* c;
	split(root, x, a, b);
	split(a, x-1, a, c);
	c = merge(c -> left, c -> right);
	root = merge( merge( a, c), b);
}

void rnk(int x){
	TREE* a;
	TREE* b;
	split(root, x-1, a, b);
	printf("%d\n", a ? a -> siz + 1 : 1);
	root = merge(a, b);
}

TREE* kth(TREE* now, int k){
	if(!now) return nullptr;
	// while(1){
	// 	if(now -> left -> siz >= k){
	// 		now = now -> left;
	// 	}else if(now -> left -> siz + 1 == k){
	// 		printf("%d\n", now -> val);
	// 		return;
	// 	}else{
	// 		k -= now -> left -> siz + 1;
	// 		now = now -> right;
	// 	}
	// }
	int left_size= now->left ? now->left->siz : 0;
	if(k==left_size+1) return now;
	else if(k<left_size+1) return kth(now->left,k);
	else return kth(root->right,k-left_size-1); // rank>left_size+1 
}

void pre(int x){
	TREE* a;
	TREE* b;
	split(root, x-1, a, b);
	TREE* temp = kth(a, a -> siz);
	root = merge(a, b);
	printf("%d\n", temp ? temp -> val : 0);
	return;
}

void nxt(int x){
	TREE* a;
	TREE* b;
	split(root, x, a, b);
	TREE* temp = kth(b, 1);
	root = merge(a, b);
	printf("%d\n",temp ? temp -> val : 0);
	return;
}

int main(){
	int n;
	int opt;
	int x;
	// srand((unsigned) time (NULL));
	
	scanf("%d",&n);
	TREE* temp;
	while(n--){
		scanf("%d %d",&opt,&x);
		if(opt==1) insert(x);
		if(opt==2) del(x);
		if(opt==3) rnk(x);
		if(opt==4) temp = kth(root,x),printf("%d\n", temp ? temp -> val : 0);
		if(opt==5) pre(x);
		if(opt==6) nxt(x);
	}
	return 0;
}
2024/8/9 16:15
加载中...