平衡树求调
查看原帖
平衡树求调
236416
_stOrz_楼主2022/1/18 16:56
#include<bits/stdc++.h>
inline int read(){
	char ch = getchar();int x = 0, r = 1;
	for(;(ch > '9' or ch < '0') and ch !='-';ch = getchar());
	if(ch == '-') r = -1, ch = getchar();
	for(;ch >= '0' and ch <= '9'; x = (x << 3) + (x << 1) + ch - '0', ch = getchar());
	return x * r;
}
struct node{
	int val, key, size, num;
	node *l, *r;
}*root, *p;

void update(node *now){
	int l = 0, r = 0;
	if(now->l != NULL) l = now->l->size;
	if(now->r != NULL) r = now->r->size;
	now->size = l + r + now->num;
}

void zag(node* &now){
	p = now->r;
	now->r = p->l;
	p->l = now;
	p->size = now->size;
	update(now);
	now = p;
}

void zig(node* &now){
	p = now->l;
	now->l = p->r;
	p->r = now;
	p->size = now->size;
	update(now);
	now = p;
}

void Insert(node* &now, int val){
	int s = 0;
	if(now == NULL){
		now = new node;
		now->key = rand();
		now->val = val;
		now->size = now->num = 1;
		now->l = now->r = NULL;
		
		return;
	}
	now->size++;
	if(now->val == val){
		now->num++;
		return;
	}
	else if(now->val < val){
		Insert(now->r, val);
		if(now->r != NULL) s = now->r->key;
		if(s > now->key) zag(now);
	}
	else{
		Insert(now->l, val);
		if(now->l != NULL) s = now->l->key;
		if(s > now->key) zig(now);
	}
}

void Delete(node* &now, int val){
	if(now == NULL) return;
	now->size--;
	if(now->val == val){
		if(now->num > 1) now->num--;
		else if(now->l == NULL) now = now->r;
		else if(now->r == NULL) now = now->l;
		else {
			int l = -1e9, r = -1e9;
			if(now->l != NULL) l = now->l->key;
			if(now->r != NULL) r = now->r->key;
			if(l > r){
				zig(now);
				Delete(now->l, val);
			}
			else{
				zag(now);
				Delete(now->r, val);
			}
		}
		return;
	}
	else if(now->val > val) Delete(now->l, val);
	else Delete(now->r, val);
}

int GetPre(int val){
	p = root;
	int res = -1;
	while(p != NULL){
		if(p->val < val){
			res = p->val;
			p = p->r;
		}
		else p = p->l;
	}
	return res;
}

int GetNext(int val){
	p = root;
	int res = 0;
	while(p != NULL){
		if(p->val > val){
			res = p->val;
			p = p->l;
		}
		else p = p->r;
	}
	return res;
}

int GetValByRank(node* now, int rank){
	int s = 0;
	if(now->l != NULL) s = now->l->size;
	if(now == NULL) return 0;
	else if(s >= rank) return GetValByRank(now->l, rank);
	else if(s + now->num >= rank) return now->val;
	else return GetValByRank(now->r, rank - s - now->num);
}

int GetRankByVal(node* now, int val){
	int s = 0;
	if(now->l != NULL) s = now->l->size;
	if(now == NULL) return 0;
	else if(now->val == val) return s + 1;
	else if(now->val > val) return GetRankByVal(now->l, val);
	else return GetRankByVal(now->r, val) + s + now->num;
}
int main(){
	srand(233);
	using namespace std;
//	root = new node;
	int n = read();
	for(int i = 1; i <= n; i++){
		switch(read()){
			case 1:{
				Insert(root, read());
				//cout << "Yes" << "\n";
				break;
			}
			case 2:{
				Delete(root, read());
				break;
			}
			case 3:{
				printf("%d\n", GetRankByVal(root, read()));
				break;
			}
			case 4:{
				printf("%d\n", GetValByRank(root, read()));
				break;
			}
			case 5:{
				printf("%d\n", GetPre(read()));
				break;
			}
			case 6:{
				printf("%d\n", GetNext(read()));
				break;
			}
		}
	}
}

2022/1/18 16:56
加载中...