splay板子求助!
查看原帖
splay板子求助!
195388
alvis楼主2021/7/29 21:33

如题。调了1h了/kel

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1e9;
int n, m, rt, idx;

struct node {
	int v, p, fl;
	int s[2], size, cnt;
}g[100010]; 

void pushup(int u) {
	g[u].size = g[g[u].s[1]].size + g[g[u].s[0]].size + g[u].cnt;
}

void pushdown(int u) {
	if(g[u].fl) {
		g[u].fl = 0;
		swap(g[u].s[1], g[u].s[0]);
		g[g[u].s[0]].fl ^= 1;
		g[g[u].s[1]].fl ^= 1;
	}
}

void ro(int u) {
	int y = g[u].p;
	int z = g[y].p;
	int k = g[y].s[1] == u;
	g[z].s[g[z].s[1] == y] = u; g[u].p = z;
	g[y].s[k] = g[u].s[k^1]; g[g[u].s[k^1]].p = y;
	g[u].s[k^1] = y; g[y].p = u;
	pushup(y);
	pushup(u);
}

void sp(int u, int k) {
	while(g[u].p != k) {
		int y = g[u].p;
		int z = g[y].p;
		if(z != k) {
			if((g[y].s[1] == u) ^ (g[z].s[1] == y)) ro(u);
			else ro(y);
		}
		ro(u);
	}
	if(!k) rt = u;
}

void insert(int v) {
	int u = rt, p = 0;
	while (u && g[u].v != v) p = u, u = g[u].s[v > g[u].v];
	if(u) {
		g[u].cnt ++;
	}else {
		u = ++ idx;
	if(p) g[p].s[v > g[p].v] = u;
	g[u].v = v;
	g[u].p = p;
	g[u].cnt = 1;
	g[u].size = 1;
	}
	
	sp(u, 0);
}

int get_k(int k) {
	int u = rt;
	while(true) {
		pushdown(u);
		if(g[g[u].s[0]].size + g[u].cnt < k) k -= g[g[u].s[0]].size + g[u].cnt, u = g[u].s[1];
		else if(g[g[u].s[0]].size >= k) u = g[u].s[0];
		else return g[u].v;
	}
	return -MAXN;
}

void out(int u) {
	pushdown(u);
	if(g[u].s[0]) out(g[u].s[0]);
	if(g[u].v > -MAXN && g[u].v < MAXN) 
		for(int i = 1;i <= g[u].cnt;i ++) cout << g[u].v << " ";
	if(g[u].s[1]) out(g[u].s[1]);
}

void find_k(int k) {
	int u = rt;
	if(!u) return ;
	while(k != g[u].v && g[u].s[k > g[u].v]) {
		u = g[u].s[k > g[u].v];
	}
	sp(u, 0);
}

int next(int k, int f) {
	find_k(k);
	int u = rt;
	if((k < g[u].v && f) || (k > g[u].v && !f)) return u;
	u = g[u].s[f];
	while(g[u].s[f^1]) u = g[u].s[f^1];
	return u; 
}

void del(int u){
	int l = next(u, 0);
	int r = next(u, 1);
	sp(l, 0), sp(r, l);
	int d = g[r].s[0];
	cout << g[d].v << "    " << d << endl;
	if(g[d].cnt > 1) {
		g[d].cnt --;
		sp(d, 0);
	} else g[r].s[0] = 0;
}

int main(){
	cin >> n;
	insert(-MAXN), insert(MAXN);
	while(n --) {
		int op ;
		cin >> op;
		//插入 
		if(op == 1) {
			int a;
			cin >> a;
			insert(a);
		}
		//删除 
		if(op == 2) {
			int a;
			del(a);
		} 
		//a的排名 
		if(op == 3) {
			int a;
			cin >> a;
			find_k(a);
			cout << g[g[rt].s[0]].size << endl;
		} 
		//排名为a数的大小 
		if(op == 4) {
			int a ;
			cin >> a;
			int ans = get_k(a+1);
			if(ans == MAXN || ans == -MAXN) cout << "No Solution" << endl;
			else cout << ans << endl;
		}
		//a的前驱 
		if(op == 5) {
		    int a;
			cin >> a;
			cout << g[next(a, 0)].v << endl;
		}
		//a的后继 
		if(op == 6) {
			int a; 
			cin >> a ;
			cout << g[next(a, 1)].v << endl;
		}
		//输出 
		if(op == 0) out(rt), cout << endl;
	}
	return 0;
} 
2021/7/29 21:33
加载中...