玄关求解
  • 板块学术版
  • 楼主MenDaRun
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/5/9 22:19
  • 上次更新2024/5/10 12:43:15
查看原帖
玄关求解
1089735
MenDaRun楼主2024/5/9 22:19

普通平衡树,我采用了Treap写本道题,随机数种子原来用的是time,测评结果很玄学,随机AC,所以就换了题解里用的随机数种子和赋值随机数的方法,但是除了个别几个点过了,其他点全MLE了,求助各位大佬

P3369

代码如下

#include<iostream>
#include<time.h>
#include<stdlib.h>

using namespace std;
int ct = 0;
int times;
const int maxn = 1e5+10;
struct tree{
	int ls,rs,pri,key,size;
};
tree node[maxn];
void update(int n)
{
	//update n's size
	node[n].size = node[node[n].ls].size + node[node[n].rs].size + 1;
}
void left_rotate(int &p) // transfer the parents node p's right son to parents node
{
	int k = node[p].rs;
	node[p].rs = node[k].ls;
	node[k].ls = p;
	node[k].size = node[p].size;
	update(p);
	p = k;
}
void right_rotate(int &p)
{
	int k = node[p].ls;
	node[p].ls = node[k].rs;
	node[k].rs = p;
	node[k].size = node[p].size;
	update(p);
	p = k;
}
void insert(int &p, int val)
{
	if(p == 0) {
		p = ++ct;
		node[p].size = 1;
		node[p].pri =rand()*rand()%19620817;
		node[p].key = val;
		return ;
	}
	node[p].size++;
	if(val >= node[p].key) insert(node[p].rs, val);
	else insert(node[p].ls,val);
	if(node[p].ls != 0 and node[node[p].ls].pri < node[p].pri) {
		right_rotate(p);
	}
	else if(node[p].rs != 0 and node[node[p].rs].pri < node[p].pri){
		 left_rotate(p);

	}
	update(p);
}
void del(int &p, int val)
{
	node[p].size--;
	if(node[p].key == val) {
		if(node[p].ls == 0 && node[p].ls == 0) {
			p = 0;
			return;
		}
		if(node[p].ls == 0 || node[p].rs == 0) {
			p = node[p].ls + node[p].rs;
			return;
		}
		if(node[node[p].ls].key < node[node[p].rs].key){
			right_rotate(p);
			del(node[p].ls,val);
			return ;
		}else{
			left_rotate(p);
			del(node[p].rs,val);
		}
	}
	if(node[p].key >= val) del(node[p].ls,val);
	else del(node[p].rs,val);
	update(p);

}
int ranks(int now, int val)
{
	if(now == 0) return 0;
	if(val > node[now].key) return node[node[now].ls].size + 1 + ranks(node[now].rs,val);
	else return ranks(node[now].ls,val);
}
int search_through_rank(int now, int rank)
{
	if(rank == node[node[now].ls].size + 1) return node[now].key;
	if(rank > node[node[now].ls].size + 1) return search_through_rank(node[now].rs, rank - node[node[now].ls].size - 1);
	return search_through_rank(node[now].ls,rank);
}
int get_front(int now, int val)
{
	if(now == 0) return 0;
	if(val <= node[now].key) return get_front(node[now].ls,val);
	int right = get_front(node[now].rs,val);
	if(right == 0) return node[now].key; 
	return right;
}
int get_behind(int now, int val)
{
	if(now == 0) return 0;
	if(val >= node[now].key) return get_behind(node[now].rs,val);
	int left = get_behind(node[now].ls,val);
	if(left == 0) return node[now].key;
	return left;
}
void zhongxu(int root)
{
	if(node[root].ls != 0) zhongxu(node[root].ls);
	cout << node[root].key << endl;
	if (node[root].rs != 0) zhongxu(node[root].rs);
}
int main()
{
	int root = 0;
	srand(19620817);
	cin >> times;
	int opt,st;
	while(times--)
	{
		cin >> opt >> st;
		if(opt == 1) insert(root,st);
		else if(opt == 2) del(root,st);
		else if(opt == 3) cout << ranks(root,st) + 1 << endl;
		else if(opt == 4) cout << search_through_rank(root,st) << endl;
		else if(opt == 5) cout << get_front(root,st) << endl;
		else cout << get_behind(root,st) << endl;
	}
//	zhongxu(root);
	return 0;
}
2024/5/9 22:19
加载中...