BZOJ 3224 普通平衡树(splay 模板)

题目

题意

中文体面,题意就不写了

思路

s p l a y splay splay 模板题,实现插入、删除、查询等操作

代码

int ch[maxn][2], pre[maxn], key[maxn], sz[maxn], cnt[maxn];
int root, tot;

void print(int u){
	// printf("%d: ls:%d rs:%d cnt:%d minn:%d maxx:%d\n", key[u], key[ch[u][0]], 
	// 	key[ch[u][1]], cnt[u], minn[u], maxx[u]);
	if(ch[u][0]) print(ch[u][0]);
	if(ch[u][1]) print(ch[u][1]);
}

void init(){
	root = tot = 0;
	ch[0][0] = ch[0][1] = pre[0] = key[0] = sz[0] = 0;
}

int judge(int x){
	return ch[pre[x]][1]==x;
}

void push_up(int x) {
	if(!x) return ;
	sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + cnt[x];
	// minn[x] = min(val[x], min(minn[ch[x][0]], minn[ch[x][1]]));
	// maxx[x] = max(val[x], max(maxx[ch[x][0]], maxx[ch[x][1]]));
	// printf("minn: x:%d ls:%d rs:%d\n", val[x], minn[ch[x][0]], minn[ch[x][1]]);
}

void setson(int x, int fa, int k) {
	if(x) pre[x] = fa;
	if(fa) {
		ch[fa][k] = x;
		push_up(fa);
	}
	else root = x;
}

void rotate(int x) {
	int f = pre[x], ff = pre[pre[x]];
	int sx = judge(x), sf = judge(f);
	int p = ch[x][!sx];
	setson(p, f, sx);
	setson(x, ff, sf);
	setson(f, x, !sx);
	push_up(f);
	push_up(x);
}

void splay(int x, int goal) { //0-root
	while(pre[x] != goal){
		if(pre[pre[x]] == goal)
			rotate(x);
		else {
			int f = pre[x];
			if(judge(x) == judge(f)) rotate(f); 
			else rotate(x);
			rotate(x);
		}
	}
	if(!goal) root = x;
}

int found(int x, int val) {
	if(!x) return 0;
	if(val == key[x]) {
		splay(x, 0);
		return x;
	}
	return val < key[x] ? found(ch[x][0], val) : found(ch[x][1], val); 
}

void ins(int &x, int val, int fa){
	if(!x) {
		x = ++tot;
		key[x] = val; pre[x] = fa;
		ch[x][0] = ch[x][1] = 0;
		sz[x] = cnt[x] = 1;
	}
	else {
		int t = x;
		if(val == key[t]) cnt[x]++;
		else val < key[t] ? ins(ch[t][0], val, t) : ins(ch[t][1], val, t); 
		push_up(t);
	}
}

void insert(int val){
	ins(root, val, 0);
	splay(tot, 0);
}

void del() {  // delete root
	if(cnt[root] > 1){
		--cnt[root];
		--sz[root];
		return;
	}
	if(!ch[root][0]){
		pre[ch[root][1]] = 0;
		root = ch[root][1];
	}
	else{
		int cur = ch[root][0];
		while(ch[cur][1]) cur = ch[cur][1];
		splay(cur, root);
		ch[cur][1] = ch[root][1];
		root = cur;
		pre[cur] = 0;
		if(ch[root][1]) pre[ch[root][1]] = root;
		push_up(root);
	}
}
void delnode(int val){
	int k = found(root, val);
	if(k) del();
}

int Kth(int u, int k){
	if(!u) return 0;
	if(k <= sz[ch[u][0]]) return Kth(ch[u][0], k);
	if(k > sz[ch[u][0]] + cnt[u]) return Kth(ch[u][1], k-sz[ch[u][0]]-cnt[u]);
	return key[u];
}

int Rank(int u, int val) {
	if(!u) return 0;
	if(key[u] == val) return sz[ch[u][0]] + 1;
	if(key[u] <  val) return sz[ch[u][0]] + cnt[u] + Rank(ch[u][1], val); 
	return Rank(ch[u][0], val);
}

int pred(int u, int val) {
	if(!u) return inf;
	if(val <= key[u]) return pred(ch[u][0], val);
	int ans = pred(ch[u][1], val);
	if(ans == inf) ans = key[u];
	return ans;
}

int succ(int u, int val){
	if (!u) return inf;
	if(val >= key[u]) return succ(ch[u][1], val);
	int ans = succ(ch[u][0], val);
	if(ans == inf) ans = key[u];
	return ans;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值