treap 14pts 求调
查看原帖
treap 14pts 求调
746023
jerrythemouselol楼主2025/7/24 16:20
#include <iostream>
#include <utility>
#include <cstdlib>
#include <ctime>
using namespace std;

typedef pair<int, int> pii;
const int maxn = 1e6 + 5;
int n, opt, x, tot, root;
int val[maxn], pri[maxn], lc[maxn], rc[maxn], siz[maxn];

void maint(int u){
	siz[u] = siz[lc[u]] + siz[rc[u]] + 1;
}

int node(int x){
	val[++tot] = x;
	pri[tot] = rand();
	siz[tot] = 1;
	lc[tot] = rc[tot] = 0;
	return tot;
}

// split tree u, first val < x, second val >= x
// returns root of the two trees
pii split(int u, int x){
	if(u == 0) return {0, 0};
	pii p;
	if(val[u] >= x){
		p = split(rc[u], x);
		lc[u] = p.second;
		p.second = u;
	}else{
		p = split(lc[u], x);
		rc[u] = p.first;
		p.first = u;
	}
	maint(u);
	return p;
}

// merge tree u and tree v (u val < v val)
// returns root after merging
int merge(int u, int v){
	if(u == 0 || v == 0) return u + v;
	if(pri[u] > pri[v]){
		rc[u] = merge(rc[u], v);
		maint(u);
		return u;
	}else{
		lc[v] = merge(u, lc[v]);
		maint(v);
		return v;
	}
} 

//insert node x
void insert(int &root, int x){
	pii rt = split(root, x);
	root = merge(merge(rt.first, node(x)), rt.second);
}

//erase only one of node x
void erase(int &root, int x){
	pii rt1 = split(root, x);
	pii rt2 = split(rt1.second, x+1);
	//rt1.first < x
	//rt2.first = x
	//rt2.second > x
	int u = merge(lc[rt2.first], rc[rt2.first]);
}

int getrank(int root, int x){
	int rank = 0, u = root;
	while(u){
		if(val[u] >= x) u = lc[u];
		else rank += siz[lc[u]] + 1, u = rc[u];
	}
	return rank;
}

int getnum(int root, int r){
	int u = root;
	while(u){
		if(siz[lc[u]] == r) break;
		if(r < siz[lc[u]]) u = lc[u];
		else r -= siz[lc[u]] + 1, u = rc[u];
	}
	return val[u];
}

int pred(int root, int x){
	return getnum(root, getrank(root, x)-1);
}

int succ(int root, int x){
	return getnum(root, getrank(root, x+1));
}

int main(){
	srand(time(0));
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf("%d%d", &opt, &x);
		if(opt == 1){
			insert(root, x);
		}else if(opt == 2){
			erase(root, x);
		}else if(opt == 3){
			printf("%d\n", getrank(root, x)+1);
		}else if(opt == 4){
			printf("%d\n", getnum(root, x-1));
		}else if(opt == 5){
			printf("%d\n", pred(root, x));
		}else if(opt == 6){
			printf("%d\n", succ(root, x));
		}
	}
	return 0;
}
2025/7/24 16:20
加载中...