Splay 板子

以后我将Splay称为Dplay!

#include <bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define N 100010
#define ll long long 
#define ld long double
#define usd unsigned
#define ull unsigned long long
//#define int long long 

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
char buf[1<<21], *p1=buf, *p2=buf;
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n;
int tot, rot;
int son[N][2], cnt[N], size[N], fa[N], val[N];
#define son(a, b) son[a][b]
#define cnt(a) cnt[a]
#define size(a) size[a]
#define fa(a) fa[a]
#define val(a) val[a]
#define loc(a) (son(fa(a), 1)==a)
#define tran(a, b) son(a, b>val(a))
#define pushup(a) size(a)=size(son(a, 0))+size(son(a, 1))+cnt(a)

void ror(int x) {
	int y=fa(x), z=fa(y), k=loc(x);
	son(z, loc(y))=x; fa(x)=z;
	son(y, k)=son(x, k^1); fa(son(x, k^1))=y;
	son(x, k^1)=y; fa(y)=x;
	pushup(y); pushup(x);
}

void splay(int x, int pos) {
	int y, z;
	while (fa(x)!=pos) {
		y=fa(x); z=fa(y);
		if (z!=pos) loc(x)^loc(y)?ror(x):ror(y);
		ror(x);
	}
	if (!pos) rot=x;
}

void ins(int x) {
	int u=rot, f=0;
	while (u&&val(u)!=x) f=u, u=tran(u, x);
	if (u) ++cnt(u);
	else {
		u=++tot;
		if (u!=rot) tran(f, x)=u;
		cnt(u)=size(u)=1;
		val(u)=x; fa(u)=f;
	}
	splay(u, 0);
}

void find(int x) {
	int u=rot;
	while (val(u)!=x&&tran(u, x)) u=tran(u, x);
	splay(u, 0);
}

int suf(int x, int f) {
	find(x);
	int u=rot;
	if (val(u)!=x && f^(x>val(u))) return u;
	u=son(u, f); f^=1;
	while (son(u, f)) u=son(u, f);
	return u;
}

void remove(int x) {
	int lst=suf(x, 0), nxt=suf(x, 1);
	splay(lst, 0); splay(nxt, lst);
	if (--cnt(son(nxt, 0))>0) splay(son(nxt, 0), 0);
	else son(nxt, 0)=0, splay(nxt, 0);
}

int rk(int x) {
	int u=rot, v;
	if (x>size(u)) return 0;
	while (1) {
		v=son(u, 0);
		if (x<=size(v)) u=v;
		else if (x>size(v)+cnt(u)) x-=size(v)+cnt(u), u=son(u, 1);
		else return val(u);
	}
}

signed main()
{
	#ifdef DEBUG
	freopen("1.in", "r", stdin);
	#endif
	
	n=read();
	ins(-INF), ins(INF);
	for (int i=1,op,x; i<=n; ++i) {
		op=read(); x=read();
		//cout<<op<<' '<<x<<endl;
		switch (op) {
			case 1: ins(x); break;
			case 2: remove(x); break;
			case 3: find(x); printf("%d\n", size(son(rot, 0))); break;
			case 4: printf("%d\n", rk(x+1)); break;
			case 5: printf("%d\n", val(suf(x, 0))); break;
			case 6: printf("%d\n", val(suf(x, 1))); break;
		}
	}

	return 0;
}
上一篇:使用Python列表查询Google App Engine数据存储区


下一篇:D.Deleting Divisors(博弈)