Treap求条
查看原帖
Treap求条
1060759
qw1234321楼主2024/1/23 13:43
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 100005, INF = 0x3f3f3f3f3f3f3f3f;
int n, k, r;
struct Treap{
	struct node{
		int l, r, size, v, dat, cnt;
	}a[N];
	int get(int v){
		a[++k].v = v;
		a[k].cnt = a[k].size = 1;
		a[k].dat = rand();
		return k;
	}
	void upd(int k){
		a[k].size = a[a[k].l].size + a[a[k].r].size + a[k].cnt;
	}
	void build(){
		get(-INF);
		get(INF);
		r = 1, a[1].r = 2;
		upd(r);
	}
	void zig(int &k){
		int t = a[k].l;
		a[k].l = a[t].r, a[t].r = k, k = t;
		upd(a[k].r);
		upd(k);
	}
	void zag(int &k){
		int t = a[k].r;
		a[k].r = a[t].l, a[t].l = k, k = t;
		upd(a[k].l);
		upd(k);
	}
	void insert(int &k, int v){
		if (!k){
			k = get(v);
			return ;
		}
		if (v == a[k].v){
			a[k].cnt++;
			upd(k);
			return ;
		}
		if (v > a[k].v){
			insert(a[k].r, v);
			if (a[k].dat < a[a[k].r].dat) zag(k);
		}
		else{
			insert(a[k].l, v);
			if (a[k].dat < a[a[k].l].dat) zig(k);
		}
		upd(k);
	}
	void remove(int &k, int v){
		if (!k){
			return ;
		}
		if (v == a[k].v){
			if (a[k].cnt > 1){
				a[k].cnt--;
				upd(k);
				return ;
			}
			if (a[k].l || a[k].r){
				if (!a[k].r || a[a[k].l].dat > a[a[k].r].dat){
					zig(k);
					remove(a[k].r, v);
				}
				else{
					zag(k);
					remove(a[k].l, v);
				}
				upd(k);
				return ;
			}
			k = 0;
			return ;
		}
		if (v > a[k].v){
			remove(a[k].r, v);
		}
		else{
			remove(a[k].l, v);
		}
		upd(k);
	}
	int ask_rank(int k, int v){
		if (!k){
			return 0;
		}
		if (v == a[k].v){
			return a[a[k].l].size + 1;
		}
		if (v < a[k].v){
			return ask_rank(a[k].l, v);
		}
		return ask_rank(a[k].r, v) + a[a[k].l].size + a[k].cnt;
	}
	int ask_val(int k, int rk){
		if (!k){
			return INF;
		}
		if (a[a[k].l].size >= rk){
			return ask_val(a[k].l, rk);
		}
		if (a[a[k].l].size + a[k].cnt >= rk){
			return a[k].v;
		}
		return ask_val(a[k].r, rk - a[a[k].l].size - a[k].cnt);
	}
	int get_pre(int k, int v){
		int pos = 1;
		while(k){
			if (v == a[k].v){
				if (a[k].l > 0){
					k = a[k].l;
					while(a[k].r > 0){
						k = a[k].r;
					}
					pos = k;
				}
				break;
			}
			if (a[k].v < v){
				if (a[k].v > a[pos].v){
					pos = k;
				}
			}
			k = v < a[k].v ? a[k].l : a[k].r;
		}
		return a[pos].v;
	}
	int get_next(int k, int v){
		int pos = 2;
		while(k){
			if (v == a[k].v){
				if (a[k].r > 0){
					k = a[k].r;
					while(a[k].l > 0){
						k = a[k].r;
					}
					pos = k;
				}
				break;
			}
			if (a[k].v > v){
				if (a[k].v < a[pos].v){
					pos = k;
				}
			}
			k = v < a[k].v ? a[k].l : a[k].r;
		}
		return a[pos].v;
	}
}T;

signed main(){
	T.build();
	cin >> n;
	for (int i = 1; i <= n; i++){
		int opt, x;
		cin >> opt >> x;
		if (opt == 1){
			T.insert(r, x);
		}
		if (opt == 2){
			T.remove(r, x);
		}
		if (opt == 3){
			cout << T.ask_rank(r, x) - 1 << "\n";
		}
		if (opt == 4){
			cout << T.ask_val(r, x + 1) << "\n";
		}
		if (opt == 5){
			cout << T.get_pre(r, x) << "\n";
		}
		if (opt == 6){
			cout << T.get_next(r, x) << "\n";
		}
	}
	return 0;
}
2024/1/23 13:43
加载中...