treap模板

没有注释自己慢慢看吧qwq

#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std;

inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}

inline int read() {
    int x = 0, fh = 1; char ch = getchar();
    for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
    for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
    return x * fh;
}

void File() {
#ifdef zjp_shadow
	freopen ("P3369.in", "r", stdin);
	freopen ("P3369.out", "w", stdout);
#endif
}

const int maxnode = 2e6 + 1e3, inf = 0x7f7f7f7f;
#define ls(o) ch[o][0]
#define rs(o) ch[o][1]
struct Treap {
	int ch[maxnode][2], val[maxnode], prio[maxnode], cnt[maxnode], cnt_sum[maxnode];

	inline void push_up(int o) {
		cnt_sum[o] = cnt[o] + cnt_sum[ls(o)] + cnt_sum[rs(o)];
	}

	void rotate(int &u, int d) {
		int v = ch[u][d];
		ch[u][d] = ch[v][d ^ 1]; ch[v][d ^ 1] = u;
		push_up(u); push_up(v); u = v;
	}

	inline int New(int val_) {
		static int Size = 0, o; o = ++ Size;
		ls(o) = rs(o) = 0; val[o] = val_;
		cnt_sum[o] = cnt[o] = 1;
		prio[o] = rand(); return o;
	}

	void Insert(int &o, int val_) {
		if (!o) { o = New(val_) ; return ; }
		if (val[o] == val_) ++ cnt[o];
		else {
			int d = (val_ > val[o]);
			Insert(ch[o][d], val_);
			if (prio[ch[o][d]] > prio[o]) rotate(o, d);
		}
		push_up(o);
	}

	void Erase(int &o) {
		if (!ls(o) && !rs(o)) { o = 0; return ; }
		int d = (prio[rs(o)] > prio[ls(o)]);
		rotate(o, d); Erase(ch[o][d ^ 1]); push_up(o);
	}

	void Delete(int &o, int val_) {
		if (val[o] == val_) { if (!(-- cnt[o])) Erase(o); push_up(o); return ; }
		int d = (val_ > val[o]);
		Delete(ch[o][d], val_); push_up(o);
	}

	int Rank(int o, int val_) {
		if (val[o] == val_) return cnt_sum[ls(o)];
		int d = (val_ > val[o]);
		return d * (cnt_sum[ls(o)] + cnt[o]) + Rank(ch[o][d], val_);
	}

	int Kth(int o, int k) {
		int res = k - cnt_sum[ls(o)];
		if (res <= 0) return Kth(ls(o), k);
		if (res > cnt[o]) return Kth(rs(o), res - cnt[o]);
		return val[o];
	}

	int Pre(int o, int val_) {
		int res = -inf, d = (val[o] < val_); 
		if (!o) return res; if (d) res = val[o];
		return max(res, Pre(ch[o][d], val_));
	}

	int Suf(int o, int val_) {
		int res = inf, d = (val[o] > val_);
		if (!o) return res; if (d) res = val[o];
		return min(res, Suf(ch[o][val_ >= val[o]], val_));
	}
} T;

int rt = 0;
int main () {
	File(); srand(time(0));
	int n = read();
	while (n --) {
		int opt = read(), val_ = read();
		if (opt == 1) T.Insert(rt, val_);
		if (opt == 2) T.Delete(rt, val_);
		if (opt == 3) printf ("%d\n", T.Rank(rt, val_) + 1);
		if (opt == 4) printf ("%d\n", T.Kth(rt, val_) );
		if (opt == 5) printf ("%d\n", T.Pre(rt, val_) );
		if (opt == 6) printf ("%d\n", T.Suf(rt, val_) );
	}
	return 0;
}
posted @ 2017-12-24 09:21  zjp_shadow  阅读(246)  评论(0编辑  收藏  举报