FHQtreap21分求调
查看原帖
FHQtreap21分求调
545873
starlife楼主2023/11/3 22:59
#include<iostream>
#include<random>
#define print(a) printf("%d\n",a)
#define bk break
#define il inline
using namespace std;
il int read()
{
	int x = 0,f = 1;char ch = getchar();
	while (ch < '0' || ch>'9'){if (ch == '-'){f = -1;}ch = getchar();}
	while (ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}
	return x * f;
}

const int N = 1e5 + 10;
std::mt19937 rnd(233);

struct Node {
	int l, r; //左右子树编号
	int key, val, size; //权值,堆权,子树大小
};
Node tr[N];
int x, y, z;
int root/*根节点编号*/, idx/*点的编号与链式前向星中cnt一致*/;

/*更新update,初始化init,分裂split,合并merge*/
int init(int key) { //初始化结点
	tr[++idx].key = key;
	tr[idx].val = rnd();
	tr[idx].size = 1;
	return idx;
}

void update(int p) { //处理子树大小
	tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + 1;
}

void split(int p, int key, int& x, int& y) { //将子树p按key权分裂成x、y两颗子树
	if (!p) {
		x = y = 0;
	} else {
		if (tr[p].key <= key) { //当前节点小,x上
			x = p;
			split(tr[p].r, key, tr[p].r, y);
		} else {
			y = p;
			split(tr[p].l, key, x, tr[p].l);
		}
		update(p);//防止更新原点
	}
}

int merge(int x, int y) {
	if (!x || !y)return (x + y);
	if (tr[x].val > tr[y].val) {
		tr[x].r = merge(tr[x].r, y); //x的右子树
		update(x);
		return x;
	} else {
		tr[y].l = merge(x, tr[x].l);
		update(y);
		return y;
	}
}

//一般操作

void insert(int key) {//插入
	split(root, key, x, y);//从根开始分裂
	root = merge(merge(x, init(key)), y);//合并x 与 key
}

void del(int key) {
	split(root, key, x, z);//裂开key为x与y
	split(x, key - 1, x, z);
	//x<=key,再分x<=key-1得到key
	y = merge(tr[y].l, tr[y].r);
	root = merge(merge(x, y), z);
	//将没有key的x、y、z合并
}

//按值查排名
void get_rank_by_key(int key) {
	split(root, key - 1, x, y);  //按key-1分割,x子树大小+1就是排名
	print(tr[x].size + 1);
	root = merge(x, y);
}

//按排名查值
void get_key(int rank) {
	int p = root;
	//循环写法
	while (p) {
		if (tr[tr[p].l].size + 1 == rank)
			break;  //找到排名了
		else if (tr[tr[p].l].size >= rank)
			p = tr[p].l;  //当前size>=rank,去左子树
		else {
			//去右子树中找rank -= 左子树大小+1(根)的排名
			rank -= tr[tr[p].l].size + 1;
			p = tr[p].r;
		}
	}
	print(tr[p].key);
}
//返回<key的最大数
void get_prev(int key) {
	//按key-1分,x最右节点就是前驱
	split(root, key - 1, x, y);
	int p = x;
	while (tr[p].r) p = tr[p].r;  //向右走
	print(tr[p].key);
	root = merge(x, y);
}

void get_next(int key) {
	split(root, key, x, y);
	int p = y;
	while (tr[p].l) p = tr[p].l;
	print(tr[p].key);
	root = merge(x, y);
}

int n,opt,qwq;
signed main() {
	n = read();
	for(int i=1;i<=n;i++){
		opt = read();
		x = read();
		switch (opt){
			case 1:
				insert(x);
				bk;
			case 2:
				del(x);
				bk;
			case 3:
				get_rank_by_key(x);
				bk;
			case 4:
				get_key(x);
				bk;
			case 5:
				get_prev(x);
				bk;
			case 6:
				get_next(x);
				bk;
			default:
				bk;
		}
	}
	return 0;
}
2023/11/3 22:59
加载中...