社区讨论

萌新Treap求助(28pt,码风还行)

P3369【模板】普通平衡树参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lo7mxqc9
此快照首次捕获于
2023/10/27 04:26
2 年前
此快照最后确认于
2023/10/27 04:26
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline int rd()
{
	int x = 0, f = 0; char v = 0;
	while(!isdigit(v)) v = getchar(), f ^= v == '-';
	while(isdigit(v)) x = (x << 1) + (x << 3) + (v ^ 48), v = getchar();
	return f ? -x : x;
}
inline void write(int x)
{
	if(x < 0) putchar('-'), x = -x;
	if(x > 9) write(x / 10);
	putchar(x % 10 ^ 48);
}
mt19937 myrand(time(0));
const int N = 1e5 + 10;
class{
	public:
	const int inf = 0x3f3f3f3f;
	int nwnd = 0;
	int val[N], key[N], lc[N], rc[N], sze[N], cnt[N];
	inline void udt(int p)
	{
		sze[p] = cnt[p] + sze[lc[p]] + sze[rc[p]];
	}
	inline void rtt(int &p, int dir)
	{
		if(dir)
		{
			int q = lc[p];
			lc[p] = rc[q], rc[q] = p;
			udt(p), udt(p = q);
		}
		else
		{
			int q = rc[p];
			rc[p] = lc[q], lc[q] = p;
			udt(p), udt(p = q);
		}
	}
	inline void newnode(int &p, int v)
	{
		p = ++nwnd;
		key[p] = myrand();
		sze[p] = cnt[p] = 1, val[p] = v, lc[p] = rc[p] = 0;
	}
	inline void irt(int &p, int v)
	{
		if(!p) return (void)(newnode(p, v));
		if(v < val[p])
		{
			irt(lc[p], v);
			if(key[lc[p]] < key[p]) rtt(p, 1);
		}
		else if(v > val[p])
		{
			irt(rc[p], v);
			if(key[rc[p]] < key[p]) rtt(p, 0);
		}
		else ++cnt[p];
		udt(p);
	}
	inline void ers(int &p, int v)
	{
		if(v < val[p]) ers(lc[p], v);
		else if(v > val[p]) ers(rc[p], v);
		else if(cnt[p] > 1) --cnt[p];
		else
		{
			if(!rc[p]) p = lc[p];
			else if(!lc[p]) p = rc[p];
			else if(key[lc[p]] < key[rc[p]]) rtt(p, 1), ers(rc[p], v);
			else rtt(p, 0), ers(lc[p], v);
		}
		udt(p);
	}
	inline int rnk(int p, int v)
	{
		if(!p) return 1;
		if(v < val[p]) return rnk(lc[p], v);
		else if(v == val[p]) return sze[lc[p]] + 1;
		else return rnk(rc[p], v) + sze[lc[p]] + cnt[p];
	}
	inline int kth(int p, int k)
	{
		if(!p) return -1;
		if(k <= sze[lc[p]]) return kth(lc[p], k);
		else if(k <= sze[lc[p]] + cnt[p]) return val[p];
		return kth(rc[p], k - sze[lc[p]] - cnt[p]);
	}
	inline int pre(int p, int v)
	{
		if(!p) return -inf;
		if(v <= val[p]) return pre(lc[p], v);
		else return max(val[p], pre(rc[p], v));
	}
	inline int nxt(int p, int v)
	{
		if(!p) return inf;
		if(v >= val[p]) return nxt(rc[p], v);
		else return min(val[p], nxt(lc[p], v));
	}
}Treap;
#define T Treap
int rt = 0, qq;
int main()
{
	qq = rd();
	for(int i = 1, op, v; i <= qq; ++i)
	{
		op = rd(), v = rd();
		if(op == 1) T.irt(rt, v);
		if(op == 2) T.ers(rt, v);
		if(op == 3) write(T.rnk(rt, v)), putchar('\n');
		if(op == 4) write(T.kth(rt, v)), putchar('\n');
		if(op == 5) write(T.pre(rt, v)), putchar('\n');
		if(op == 6) write(T.nxt(rt, v)), putchar('\n');
	}
	return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...