44分求调
查看原帖
44分求调
426187
Ailuomangacencei楼主2023/10/5 21:12
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5,INF = 1e9;
int n, root;
int son[N][2], cnt[N], sz[N], rnd[N], val[N], idx;

int newbuild(int x){
	val[++idx] = x;
	rnd[idx] = rand();
	cnt[idx] = sz[idx] = 1;
	return idx;
}

inline void pushup(int u){
	sz[u] = sz[son[u][0]] + sz[son[u][1]] + cnt[u];
}

void build(){
	root = newbuild(-INF), son[root][1] = newbuild(INF);
	pushup(root);
}

void rotate(int &id, int d){
	int temp = son[id][d ^ 1];
	son[id][d ^ 1] = son[temp][d];
	son[temp][d] = id;
	id = temp;
	pushup(son[id][d]), pushup(id);
}

void add(int &id, int x){
	if (!id) {id = newbuild(x); return ;}
	if (val[id] == x) cnt[id] ++ ;
	else {
		int d = 0;if (x > val[id]) d = 1;
		add(son[id][d], x);
		if (rnd[son[id][d]] < rnd[id]) rotate(id, d ^ 1);
	}
}

void rmv(int &id, int x){
	if (!id) return ;
	if (val[id] == x){
		if (cnt[id] > 1) {cnt[id] --;pushup(id); return ;}
		if (son[id][0] && son[id][1]){
			int d = 0;if (rnd[son[id][0]] > rnd[son[id][1]]) d = 1;
			rotate(id, d ^ 1);
			rmv(id, x);		
		}
		else {	
			int d = 0;if (son[id][1]) d = 1;
			id = son[id][d];
		}
	}
	else {
		if (x < val[id]) rmv(son[id][0], x);
		else rmv(son[id][1], x);
	}
	pushup(id);
}

int get_rank(int id, int x){
	if (!id) return 1;
	if (val[id] == x) return sz[son[id][0]] + 1;
	else {
		if (x < val[id]) return get_rank(son[id][0], x);
		else return sz[son[id][0]] + cnt[id] + get_rank(son[id][1], x);	
	}
}

int get_val(int id, int rank){
	if (!id) return INF;
	if (rank <= sz[son[id][0]]) return get_val(son[id][0], rank);
	else {
		if (rank <= sz[son[id][0]] + cnt[id]) return val[id];
		else return get_val(son[id][1], rank - sz[son[id][0]] - cnt[id]);
	}
}

int get_pre(int x){
	int id = root, pre;
	while (id){
		if (x > val[id]) pre = val[id], id = son[id][1];
		else id = son[id][0];
	}
	return pre;
}

int get_nxt(int x){
	int id = root, nxt;
	while (id){
		if (x < val[id]) nxt = val[id], id = son[id][0];
		else id = son[id][1]; 
	}
	return nxt;
}

int main(){
//	freopen("3369.in","r", stdin);
	build();
	scanf("%d", &n);
	while (n --){
		int opt, x;
		scanf("%d%d", &opt, &x);
		if (opt == 1) add(root, x);
		if (opt == 2) rmv(root, x);
		if (opt == 3) printf("%d\n", get_rank(root, x) - 1);
		if (opt == 4) printf("%d\n", get_val(root, x + 1));
		if (opt == 5) printf("%d\n", get_pre(x));
		if (opt == 6) printf("%d\n", get_nxt(x));
	}
	return 0;
}

44分求调

2023/10/5 21:12
加载中...