Treap 死循环MLE了,求调
查看原帖
Treap 死循环MLE了,求调
538899
jia_hua_wu楼主2022/11/19 18:05
#include<bits/stdc++.h>
using namespace std;

const int N = 1e5+5;

struct node{
	int val,pr;
	int left,right;
	int count,num;
 } tre[N];
int n,opt,x;
int root = -1;
int counter = 0;

int get_rand()
{
	return rand()%32768+1;
}

int count(int u)
{
	if (u == -1) {
		return 0;
	}
	return tre[u].count;
}

void pushup(int u)
{
	tre[u].count = count(tre[u].left) + tre[u].num + count(tre[u].right);
}

// f is parent of u
// if u is root, f is -1
void right_rotate(int u, int f)
{
	int c = tre[u].left;
	if (c != -1) {
		tre[u].left = tre[c].right;
	}
	tre[c].right = u;
	pushup(u);
	pushup(c);
	if (f == -1) {
		root = c;
	} else if (tre[f].left == u) {
		tre[f].left = c;
	} else if (tre[f].right == u) {
		tre[f].right = c;
	}
}

void left_rotate(int u, int p)
{
	int c = tre[u].right;
	if (c != -1) {
		tre[u].right = tre[c].left;
	}
	tre[c].left = u;
	pushup(u);
	pushup(c);
	if (p == -1) {
		root = c;
	} else if (tre[p].left == u) {
		tre[p].left = c;
	} else if (tre[p].right == u) {
		tre[p].right = c;
	}
}

void add(int x, int u, int f)
{
	if (tre[u].pr == 0) {
		tre[u].pr = get_rand();
		tre[u].val = x;
		tre[u].left = -1;
		tre[u].right = -1;
		tre[u].num = 1;
		tre[u].count = 1;
	} else if (x == tre[u].val) {
		tre[u].num++;
		pushup(u);
	} else if (x < tre[u].val) {
		if (tre[u].left == -1) {
			tre[u].left = counter++;
		}
		add(x, tre[u].left, u);
		pushup(u);
		if (tre[tre[u].left].pr > tre[u].pr) {
			right_rotate(u, f);
		}
	} else {
		if (tre[u].right == -1) {
			tre[u].right = counter++;
		}
		add(x, tre[u].right, u);
		pushup(u);
		if (tre[tre[u].right].pr > tre[u].pr) {
			left_rotate(u, f);
		}
	}
}

void my_add(int x)
{
	if (root == -1) {
		root = counter++;
	}
	add(x, root, -1);
	pushup(root);
}

void replace_by_child(int c, int u, int f)
{
	if (f == -1) {
		root = c;
	} else if (tre[f].left == u) {
		tre[f].left = c;
	} else if (tre[f].right == u) {
		tre[f].right = c;
	}
}

void del(int x, int u, int f)
{
	if (u == -1) {
		return;
	}
	if (x == tre[u].val && tre[u].num == 1) {
//		while(left != -1 && right != -1 )
		if (tre[u].left == -1) {
			int c = tre[u].right;
			replace_by_child(c, u, f);
			pushup(c);
		} else if (tre[u].right == -1) {
			int c = tre[u].left;
			replace_by_child(c, u, f);
			pushup(c);
		} else {
			if (tre[tre[u].left].pr > tre[tre[u].right].pr) {
				right_rotate(u, f);
				del(x, u, tre[u].left);
			} else {
				left_rotate(u, f);
				del(x, u, tre[u].right);
			}
		}
	} else if (x == tre[u].val) {
		tre[u].num--;
		pushup(u);
	} else if (x < tre[u].val) {
		del(x, tre[u].left, u);
		pushup(u);
	} else {
		del(x, tre[u].right, u);
		pushup(u);
	}
}

void my_del(int x)
{
	del(x, root, -1);
}

int find_by_rank(int rank, int u) 
{
	if (count(tre[u].left) + 1 <= rank && rank < count(tre[u].left) + tre[u].num + 1) {
		return tre[u].val;
	} else if (rank < count(tre[u].left) + 1) {
		return find_by_rank(rank, tre[u].left);
	} else {
		return find_by_rank(rank - (count(tre[u].left) + tre[u].num), tre[u].right);
	}
}

int my_find_by_rank(int rank)
{
	return find_by_rank(rank, root);
}

int get_rank(int x, int u)
{
	if (x == tre[u].val) {
		return count(tre[u].left) + 1;
	} else if (x < tre[u].val) {
		return get_rank(x, tre[u].left);
	} else {
		return count(tre[u].left) + tre[u].num + get_rank(x, tre[u].right);
	}
}

int my_get_rank(int x)
{
	return get_rank(x, root);
}

int find_pred(int x, int u)
{
	if (u == -1) {
		return -1e7-5;
	}
	if (x <= tre[u].val) {
		return find_pred(x, tre[u].left);
	} else {
		int result = find_pred(x, tre[u].right);
		if (result == -1e7-5) {
			return tre[u].val;
		}
		return result;
	}
}

int my_find_pred(int x)
{
	return find_pred(x, root);
}

int find_succ(int x, int u)
{
	if (u == -1) {
		return 1e7+5;
	}
	if (x >= tre[u].val) {
		return find_succ(x, tre[u].right);
	} else {
		int result = find_succ(x, tre[u].left);
		if (result == 1e7+5) {
			return tre[u].val;
		}
		return result;
	}
}

int my_find_succ(int x)
{
	return find_succ(x, root);
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d %d",&opt,&x);
		if(opt == 1) my_add(x);
		else if(opt == 2) my_del(x);
		else if(opt == 3) printf("%d\n",my_get_rank(x));
		else if(opt == 4) printf("%d\n",my_find_by_rank(x));
		else if(opt == 5) printf("%d\n",my_find_pred(x));
		else printf("%d\n",my_find_succ(x));
	}
	return 0;
}
2022/11/19 18:05
加载中...