0分splay
查看原帖
0分splay
94933
T1anBooy楼主2024/10/5 20:22

本蒟蒻首次接触splay,求大佬指点

#include <bits/stdc++.h>

using namespace std;

const int N = 1e4+10;
const long long INF = (1<<31) - 1;

 int fa[N], lc[N], rc[N], sz[N], cnt[N], val[N];
 int rt, tot;

 inline int read ();
 bool direction (int );
 void Splay (int , int );
 inline void inst (int );
 void Rotate (int );
 inline int Find (int );
 inline void inst (int );
 inline void join (int , int );
 inline void del (int );
 inline int rk (int );
 inline void update (int );
 inline int pre (int );
 inline int nxt (int );
 inline int Findk (int );

int main () {
	int q = read();
	while (q --) {
		int op = read();
		switch (op){
			
			case 1:{
				int v = read();
				int ans = rk(v);
				cout << ans << endl;
				break;
			} 
			case 2:{
				int x = read();
				int ans = Findk(x);
				cout << ans << endl;
				break;
			}
			case 3:{
				int x = read();
				inst(x);
				int ans = val[pre(x)];
				del(x);
				cout << ans << endl;
				break;
			}
			case 4:{
				int x = read();
				inst(x);
				int ans = val[nxt(x)];
				del(x);
				cout << ans << endl;
				break;
			}
			case 5:{
				int x = read();
				inst(x);
				break;
			}
			
			/*
			case 1:inst(x);break;
			case 2:del(x);break;
			case 3:printf ("%d\n", rk(x));break;
			case 4:printf ("%d\n", Findk(x));break;
			case 5:inst(x);printf("%d/n", val[pre(x)]);del(x);break;
			case 6:inst(x);printf("%d\n", val[nxt(x)]);del(x);break;
			*/
		}
	}
	return 0;
}

inline int read () {
	int x = 0, flag = 1;
	char ch = getchar ();
	while (!isdigit(ch)) { if (ch == '-') flag = -1; ch = getchar();}
	while (isdigit(ch)) { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
	return x * flag;
}

bool direction (int x) { //判断链fa[x]-x的方向 
	return rc[fa[x]] == x;
}

void Splay (int x, int tar) {
	while (fa[x]!=tar) {
		if (fa[fa[x]] != tar) direction(x) == direction(fa[x]) ? Rotate(fa[x]) : Rotate(x);
		Rotate(x);//先转父亲再转自己 
	}
	if (!tar) rt = x;//Splay(x,0)代表x旋转到根节点
	return ; 
}
 
inline void inst (int v) {
	int u = rt, Fa = 0;
	while (u != 0 && v != val[u]) {
		Fa = u;
		u = (v > val[u] ? rc[u] : lc[u]);
	}
	if (u) cnt[u] ++;
	else {
		u = tot++;
		if (Fa == 0) rt = u;
		else (v > val[u] ? rc[u] : lc[u]) = u;
		val[u] = v;
		fa[u] = Fa;
		cnt[u] = 1;
		sz[u] = 1;
	}
	Splay(u, 0);
	return ;
}

void Rotate (int x) {
	int y = fa[x], z = fa[y];
	int b = (lc[y] == x) ? rc[x] : lc[x];
	fa[x] = z;
	fa[y] = x;
	if (b) fa[b] = y;
	if (z) (y == lc[z] ? lc[z] : rc[z]) = x;
	if (x == lc[y]) rc[x] = y, lc[y] = b;
	else lc[x] = y, rc[y] = b;
	return ;
}

inline int Find (int v) {
	int x = rt;
	while (x) {
		if (v == val[x]) break;
		if (v > val[x]) x = rc[x];
		else x = lc[x];
	}
	if (x) Splay(x, 0);
	return x;
}


inline void join (int u, int v) {
	fa[u] = fa[v] = 0;
	int w = u;
	while (rc[w]) w = rc[w];
	Splay(w, 0);
	rc[w] = v;
	fa[v] = w;
	return ;
}

inline void del (int u) {
	Splay(u, 0);
	if (!lc[u] || !rc[u]) fa[rt = lc[u] + rc[u]] = 0;
	else join (lc[u], rc[u]);
	lc[u] = rc[u] = 0;
	return ;
}

inline int rk (int v) {
	int x = Find(v);
	return sz[lc[x]] + 1;
}

inline void update (int x) {
	sz[x] = sz[lc[x]] + sz[rc[x]];
}

inline int pre (int x) { //前驱 
	int temp = Find(x);
	int u = lc[rt];
	if (u == 0) return -INF;
	while (rc[u]) u = rc[u];
	return u;
}

inline int nxt (int x) { //后驱 
	int temp = Find(x);
	int u = rc[rt];
	if (u == 0) return INF;
	while (lc[u]) u = lc[u];
	return u;
}

inline int Findk (int k) {
	int u = rt;
	if (sz[u] < k) return -1;//不存在
	while (true) {
		if (k < sz[lc[u]] + cnt[u]) u = lc[u];
		else if (k == sz[lc[u]] + cnt[u]) return u;
		else u = rc[u], k -= sz[lc[u]] + cnt[u];
	} 
}
2024/10/5 20:22
加载中...