普通Treap 20pts求助
查看原帖
普通Treap 20pts求助
308107
Xu__楼主2021/12/29 20:23

只AC了#1和#12,其他全WA(

评测记录

#include <bits/stdc++.h>
#define int long long
#define FL(xx, yy, zz) memset(xx, yy, sizeof(int) * (zz))
#define Efor(xx, yy) for(int xx = Head[yy]; xx; xx = Next[xx])
#define Lfor(xx, yy, zz, xyz, ...) for(int xx = yy, ##__VA_ARGS__; xx <= zz; xx += xyz)
#define Rfor(xx, yy, zz, xyz, ...) for(int xx = yy, ##__VA_ARGS__; xx >= zz; xx -= xyz)
using namespace std;
struct FastIN
{
	char buf[(1 << 21) + 100], *p, *e;
	int getChar()
	{
		if (p == e) p = buf, e = buf + fread(buf, 1, (1 << 21), stdin);
		return p == e ? EOF : *p++;
	}
	template<typename T>
	FastIN& operator>>(T& x)
	{
		char c, l;
		for (c = 0; !isdigit(c); c = getChar()) l = c;
		for (x = 0; isdigit(c); c = getChar()) x = x * 10 - '0' + c;
		if (l == '-') x = -x;
		return *this;
	}
} IN;
const int kN = 1e6 + 16, INF = ~0ul >> 1;
int n, tot, root;
mt19937 Rand(time(NULL));
struct Treap {
	int l, r;
	int val, dat;
	int size, cnt;
} T[kN];

void Up(int p) {
	T[p].size = T[T[p].l].size + T[T[p].r].size + T[p].cnt;
}

int New(int x) {
	T[++tot].val = x, T[tot].dat = Rand();
	T[tot].cnt = T[tot].size = 1;
	return tot;
}

void Build() {
	New(-INF), New(INF);
	root = 1, T[1].r = 2;
	Up(root);
}

void Left(int& x) {
	int q = T[x].r;
	T[x].r = T[q].l, T[q].l = x, x = q;
	Up(T[x].l), Up(x);
}

void Right(int& x) {
	int q = T[x].l;
	T[x].l = T[q].r, T[q].r = x, x = q;
	Up(T[x].r), Up(x);
}

void Insert(int& p, int val) {
	if (!p) {
		p = New(val); return ;
	}
	else if (T[p].val == val) {
		T[p].cnt++, Up(p);
		return ;
	}
	else if (val < T[p].val) {
		Insert(T[p].l, val);
		if (T[p].dat < T[T[p].l].dat) Right(p);
	}
	else {
		Insert(T[p].r, val);
		if (T[p].dat < T[T[p].r].dat) Left(p);
	}
}

void Remove(int& p, int val) {
	if (!p) return ;
	if (T[p].val == val) {
		if (T[p].cnt > 1) {
			T[p].cnt--, Up(p);
			return ;
		}
		if (T[p].l or T[p].r) {
//			if (T[p].l == 0 or T[T[p].l].dat < T[T[p].r].dat) Left(p), Remove(T[p].l, val);
//			else										 Right(p), Remove(T[p].r, val);
			if (T[p].r == 0 or T[T[p].l].dat > T[T[p].r].dat) Right(p), Remove(T[p].r, val);
			else											  Left(p), Remove(T[p].l, val);
			Up(p);
		}
		else p = 0;
		return ;
	}
	(val < T[p].val) ? Remove(T[p].l, val) : Remove(T[p].r, val);
	Up(p);
}

int GetRankByVal(int p, int val) {
	if (!p) return 0;
	if (val == T[p].val) return T[T[p].l].size + 1;
	if (val < T[p].val) return GetRankByVal(T[p].l, val);
	else return GetRankByVal(T[p].r, val) + T[T[p].l].size + T[p].cnt;
}

int GetValByRank(int p, int rank) {
	if (!p) return 0;
	if (T[T[p].l].size >= rank) return GetValByRank(T[p].l, rank);
	else if (T[T[p].l].size + T[p].cnt >= rank) return T[p].val;
	else return GetValByRank(T[p].r, rank - T[T[p].l].size - T[p].cnt);
}

int GetPre(int val) {
	int ans = 1, p = root;
	while (p) {
		if (val == T[p].val) {
			if (T[p].l) {
				p = T[p].l;
				while (T[p].r) p = T[p].r;
				ans = p;
			}
			break;
		} else {
			if (T[p].val < val and T[p].val > T[ans].val) ans = p;
			p = (val < T[p].val ? T[p].l : T[p].r);
		}
	}
	return T[ans].val;
}

int GetNext(int val) {
	int ans = 2, p = root;
	while (p) {
		if (val == T[p].val) {
			if (T[p].r) {
				p = T[p].r;
				while (T[p].l) p = T[p].l;
				ans = p;
			}
			break;
		} else {
			if (T[p].val > val and T[p].val < T[ans].val) ans = p;
			p = (val < T[p].val ? T[p].l : T[p].r);
		}
	}
	return T[ans].val;
}

signed main() {
#ifdef FIO
    freopen("D:/Code/In.in", "r", stdin);
    freopen("D:/Code/Out.out", "w", stdout);
#endif
	IN >> n;
	Lfor (i, 1, n, 1, opt, x) {
		IN >> opt >> x;
		switch (opt) {
			case 1 : Insert(root, x); break;
			case 2 : Remove(root, x); break;
			case 3 : cout << GetRankByVal(root, x - 1) + 1 << "\n"; break;
			case 4 : cout << GetValByRank(root, x) << "\n"; break;
			case 5 : cout << GetPre(x) << "\n"; break;
			case 6 : cout << GetNext(x) << "\n"; break;
		}
	}
    return 0;
}


2021/12/29 20:23
加载中...