【模板】【Treap】【Luogu P3369】平衡树

链接

Luogu P3369

题目描述

在这里插入图片描述

思路

Treap模板

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

int size[100005], s[100005][2];
int v[100005], pos[100005];
int n, root, opt, x, cnt, num;

void up(int x)
{
    
    
	size[x] = size[s[x][0]] + size[s[x][1]] + 1;
}

void trrn(int &num, int p)
{
    
    
	int t=s[num][p];
    s[num][p]=s[t][!p],s[t][!p]=num,up(num),up(t),num=t;
}

void insert(int x, int &num)
{
    
    
	if(!num) 
	{
    
    
		num = ++cnt; 
		size[num] = 1;
		v[num] = x;
		pos[num] = rand();
		return;
	}//当前点是空点
	size[num]++;
	if(x <= v[num]) {
    
    
		insert(x, s[num][0]);
		if(pos[s[num][0]] < pos[num]) trrn(num, 0);
	}
	else {
    
    
		insert(x, s[num][1]);
		if(pos[s[num][1]] < pos[num]) trrn(num, 1);
	}
	return;
}

void del(int x, int &num)
{
    
    
	if(v[num] == x) {
    
    
		if(s[num][0] * s[num][1] == 0) {
    
    num = s[num][0] + s[num][1]; return;}//直接让它父亲连向它唯一的儿子
		else if(pos[s[num][0]] > pos[s[num][1]]) {
    
    
			trrn(num, 1);
			del(x, s[num][0]);
		}
		else {
    
    
			trrn(num, 0);
			del(x, s[num][1]);
		}
	}
	else if(v[num] > x) del(x, s[num][0]);
	else del(x, s[num][1]);
	up(num);
}

int ask_rank(int x, int num)
{
    
    
	if(!num) return 1;
	if(v[num] >= x) return ask_rank(x, s[num][0]);
	return ask_rank(x, s[num][1]) + size[s[num][0]] + 1;
}

int find_rank(int x, int num)
{
    
    
	if(size[s[num][0]] == x - 1) return v[num];
	if(size[s[num][0]] >= x) return find_rank(x, s[num][0]);
	return find_rank(x - size[s[num][0]] - 1, s[num][1]);
}

int find_pre(int x, int num)
{
    
    
	if(!num) return -20000005;
	if(v[num] < x) return max(v[num], find_pre(x, s[num][1]));
	else return find_pre(x, s[num][0]);
}

int find_nxt(int x, int num)
{
    
    
	if(!num) return 20000005;
	if(v[num] > x) return min(v[num], find_nxt(x, s[num][0]));
	else return find_nxt(x, s[num][1]);
}

int main()
{
    
    
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i)
	{
    
    
		scanf("%d%d", &opt, &x);
		if(opt == 1) insert(x, num);
		if(opt == 2) del(x, num);
		if(opt == 3) printf("%d\n", ask_rank(x, num));
		if(opt == 4) printf("%d\n", find_rank(x, num));
		if(opt == 5) printf("%d\n", find_pre(x, num));
		if(opt == 6) printf("%d\n", find_nxt(x, num));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/LTH060226/article/details/119789154