Splay 44pts求条,玄关
查看原帖
Splay 44pts求条,玄关
891606
2023gdgz01楼主2024/8/20 10:37

record

#include <cstdio>
#define int long long

template <typename T, const int _size> class Splay {
	protected:
		T w[_size + 5];
		int root, cur, fa[_size + 5], cnt[_size + 5], _Size[_size + 5], child[_size + 5][2];
		inline bool get(int u) {
			return child[fa[u]][1] == u;
		}
		inline void resize(int u) {
			_Size[u] = cnt[u] + _Size[child[u][0]] + _Size[child[u][1]];
		}
		inline void clear(int u) {
			w[u] = fa[u] = cnt[u] = _Size[u] = child[u][0] = child[u][1] = 0;
		}
		inline void rotate(int u) {
			int mod = get(u), father = fa[u], grandfa = fa[father];
			child[father][mod] = child[u][mod ^ 1];
			if (child[u][mod ^ 1])
				fa[child[u][mod ^ 1]] = father;
			child[u][mod ^ 1] = father;
			fa[father] = u;
			fa[u] = grandfa;
			if (grandfa)
				child[grandfa][father == child[grandfa][1]] = u;
			resize(u);
			resize(father);
		}
		inline void splay(int u) {
			for (register int i = fa[u]; fa[u]; rotate(u)) {
				i = fa[u];
				if (fa[i]) {
					if (get(u) == get(i))
						rotate(i);
					else
						rotate(u);
				}
			}
			root = u;
		}
		inline int prev() {
			int u = child[root][0];
			if (!u)
				return u;
			for (; child[u][1]; u = child[u][1]);
			splay(u);
			return u;
		}
		inline int next() {
			int u = child[root][1];
			if (!u)
				return u;
			for (; child[u][0]; u = child[u][0]);
			splay(u);
			return u;
		}
	public:
		Splay() {}
		~Splay() {}
		inline void insert(T v) {
			if (!root) {
				++cur;
				root = cur;
				w[root] = v;
				cnt[root] = 1;
				resize(root);
				return;
			}
			for (register int u = root, father = 0; ;) {
				if (w[u] == v) {
					++cnt[u];
					resize(u);
					resize(father);
					splay(u);
					break;
				}
				father = u;
				u = child[u][w[u] < v];
				if (!u) {
					++cur;
					w[cur] = v;
					fa[cur] = father;
					++cnt[cur];
					child[father][w[father] < v] = cur;
					resize(cur);
					resize(father);
					splay(cur);
					break;
				}
			}
		}
		inline int rank(T v) {
			for (register int u = root, ans = 0; ;) {
				if (w[u] > v)
					u = child[u][0];
				else {
					ans += _Size[child[u][0]];
					if (!u)
						return ans + 1;
					if (w[u] == v) {
						splay(u);
						return ans + 1;
					}
					u = child[u][1];
					ans += cnt[u];
				}
			}
		}
		inline T value(int rank) {
			for (register int u = root; ;) {
				if (child[u][0] && _Size[child[u][0]] >= rank)
					u = child[u][0];
				else {
					rank -= cnt[u] + _Size[child[u][0]];
					if (rank <= 0) {
						splay(u);
						return w[u];
					}
					u = child[u][1];
				}
			}
		}
		inline void remove(T v) {
			int t1 = rank(v), t2, t3;
			if (cnt[root] > 1) {
				--cnt[root];
				resize(root);
				return;
			}
			if (child[root][0]) {
				if (child[root][1]) {
					t2 = root;
					t3 = prev();
					fa[child[t2][1]] = t2;
					child[t3][1] = child[t2][1];
					clear(t2);
					resize(root);
				}
				else {
					t2 = root;
					root = child[root][0];
					fa[root] = 0;
					clear(t2);
				}
			}
			else {
				if (child[root][1]) {
					t2 = root;
					root = child[root][1];
					fa[root] = 0;
					clear(t2);
				}
				else {
					clear(root);
					root = 0;
				}
			}
		}
		inline T prev(T v) {
			insert(v);
			T ans = w[prev()];
			remove(v);
			return ans;
		}
		inline T next(T v) {
			insert(v);
			T ans = w[next()];
			remove(v);
			return ans;
		}
};

int n, x, opt;
Splay<int, 100000> tree;

signed main() {
	scanf("%lld", &n);
	while (n--) {
		scanf("%lld%lld", &opt, &x);
		switch (opt) {
			case 1:
				tree.insert(x);
				break;
			case 2:
				tree.remove(x);
				break;
			case 3:
				printf("%lld\n", tree.rank(x));
				break;
			case 4:
				printf("%lld\n", tree.value(x));
				break;
			case 5:
				printf("%lld\n", tree.prev(x));
				break;
			case 6:
				printf("%lld\n", tree.next(x));
				break;
		}
	}
	return 0;
}

马蜂十分奇特

2024/8/20 10:37
加载中...