求帮忙把这个已过splay的模板调到过加强版P6136
  • 板块学术版
  • 楼主XSean
  • 当前回复8
  • 已保存回复8
  • 发布时间2023/6/11 15:44
  • 上次更新2023/10/23 13:22:13
查看原帖
求帮忙把这个已过splay的模板调到过加强版P6136
546830
XSean楼主2023/6/11 15:44

P6136

#include <bits/stdc++.h>

#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define pre(i, a, b) for(int i = (a); i >= (b); i--)
#define Ede(i, u) for(int i = h[u]; i; i = ne[i])
#define go(i, a) for(auto i : a)
//#define int long long
#define LL long long
#define ULL unsigned long long
#define PII pair<int, int>
#define PIL pair<int, long long>
#define PLI pair<long long, int>
#define PLL pair<long long, long long>
#define mp make_pair
#define eb emplace_back
#define opb pop_back
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define sf scanf
#define prf printf
#define el putchar('\n')
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define mmc(arr1, arr2) memcpy(arr1, arr2, sizeof(arr2))
#define Db(x) prf("test(%s): ", x)
const int inf = 0x3f3f3f3f;

template <typename T> inline void rd(T &x){
	x = 0; bool f = true; char ch = getchar();
	while(ch < '0' || ch > '9'){ if(ch == '-') f = false; ch = getchar();}
	while(ch >= '0' && ch <= '9'){ x = (x << 1) + (x << 3) + (ch ^ '0'); ch = getchar();}
	if(!f) x = -x;
}
template <typename T, typename ...Args> inline void rd(T &x, Args &...args){ rd(x); rd(args...);}
#define ls(x) ptr[x].s[0]
#define rs(x) ptr[x].s[1]
using namespace std;

const int N = 1e5 + 10;
int n, m;
struct Node{
	int s[2];
	int p;
	int v;
	int cnt;
	int siz;
	void init(int p1, int v1){
		p = p1, v = v1;
		cnt = siz = 1;
	}
}ptr[N];
int root, idx;
void pushup(int x){
	ptr[x].siz = ptr[ls(x)].siz + ptr[rs(x)].siz + ptr[x].cnt;
}
void rotate(int x){ //旋x,y 
	int y = ptr[x].p, z = ptr[y].p;
	int k = rs(y) == x;
	//组x,z 
	ptr[z].s[rs(z) == y] = x; //swap(x,y) 
	ptr[x].p = z;
	//x.son的调换->y.son
	ptr[y].s[k] = ptr[x].s[k^1];
	ptr[ptr[x].s[k^1]].p = y;
	//组x,y
	ptr[x].s[k^1] = y;
	ptr[y].p = x; 
	//先y,后x 
	pushup(y), pushup(x);
}
void splay(int x, int k){
	while(ptr[x].p != k){
		int y = ptr[x].p, z = ptr[y].p;
		if(z != k) ((ls(z) == y) ^ (ls(y) == x)) ? rotate(x) : rotate(y);
		rotate(x);
	}
	if(k == 0) root = x;
}
void insert(int v){
	int x = root, p = 0;
	while(x && ptr[x].v != v){
		p = x, x = ptr[x].s[v > ptr[x].v]; 
	}
	if(x) ptr[x].cnt++;
	else{
		x = ++idx;
		ptr[p].s[v > ptr[p].v] = x;
		ptr[x].init(p, v);
	}
	splay(x, 0);
}
void find(int v){
	int x = root;
	while(ptr[x].s[v > ptr[x].v] && v != ptr[x].v){
		x = ptr[x].s[v > ptr[x].v];
	}
	splay(x, 0);
}
int get_pre(int v){
	find(v);
	int x = root;
	if(v > ptr[x].v) return x;
	x = ls(x);
	while(rs(x)) x = rs(x);
	return x;
}
int get_suc(int v){
	find(v);
	int x = root;
	if(v < ptr[x].v) return x;
	x = rs(x);
	while(ls(x)) x = ls(x);
	return x;
}
void del(int v){
	int pre = get_pre(v), suc = get_suc(v);
	splay(pre, 0), splay(suc, pre);
	int del = ls(suc);
	if(ptr[del].cnt > 1) ptr[del].cnt--, splay(del, 0);
	else ls(suc) = 0, splay(suc, 0);
}
int get_rk(int v){
	find(v);
	return ptr[ls(root)].siz;
}
int get_val(int k){
	int x = root;
	while(true){
		int y = ls(x);
		if(ptr[y].siz + ptr[x].cnt < k){
			k -= (ptr[y].siz + ptr[x].cnt);
			x = rs(x);
		}else if(ptr[y].siz >= k) x = y;
		else break; //ptr[y].siz < k <= ptr[y].siz + ptr[x].cnt
	}
	splay(x, 0);
	return ptr[x].v;
}
int main(){
	/*
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
	*/
	rd(n);
	insert(-inf), insert(inf);
	rep(i, 1, n){
		int ins, x; rd(ins, x);
		if(ins == 1) insert(x);
		else if(ins == 2) del(x);
		else if(ins == 3) prf("%d\n", get_rk(x));
		else if(ins == 4) prf("%d\n", get_val(x + 1));
		else if(ins == 5) prf("%d\n", ptr[get_pre(x)].v);
		else prf("%d\n", ptr[get_suc(x)].v); 
	}

	return 0;
}





2023/6/11 15:44
加载中...