Splay求调36分
查看原帖
Splay求调36分
701221
Chr0n1CleC楼主2022/8/18 18:25

感觉我写假了

(2WA + 6TLE)

#include<cstdio>
#define N 1000009

struct Splay
{
	int rt, tot, fa[N], ch[N][2], val[N], cnt[N], siz[N];
	inline void updata(int x)
	{
		siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x];
	}
	inline bool get(int x)
	{
		return x == ch[fa[x]][1];
	}
	inline void clear(int x)
	{
		fa[x] = ch[x][0] = ch[x][1] = siz[x] = val[x] = cnt[x] = 0;
	}
	inline void rorate(int x)
	{
		int y = fa[x], z = fa[y], f = get(x);
		ch[y][f] = ch[x][f ^ 1];
		if (ch[x][f ^ 1])
			fa[ch[x][f ^ 1]] = y;
		ch[x][f ^ 1] = y;
		fa[y] = x;
		fa[x] = z;
		if (z)
			ch[z][y == ch[z][1]] = x;
		updata(x), updata(y);
	}
	inline void splay(int x)
	{
		for (int i = fa[x];i = fa[x], i;rorate(x))
			if (fa[i])
				rorate(get(x) == get(i) ? i : x);
		rt = x;
	}
	inline void insert(int x)
	{
		if (!rt)
		{
			rt = ++ tot;
			val[tot] = x;
			cnt[tot] ++;
			updata(rt);
			return;
		}
		int cur = rt, f = 0;
		while (1)
		{
			if (val[cur] == x)
			{
				cnt[cur] ++;
				updata(cur);
				updata(f);
				splay(cur);
				break;
			}
			f = cur;
			cur = ch[cur][val[cur] < x];
			if (!cur)
			{
				val[++ tot] = x;
				cnt[tot] ++;
				fa[tot] = f;
				ch[f][val[f] < x] = tot;
				updata(tot);
				updata(f);
				splay(tot);
				break;
			}
		}
	}
	inline int rank(int x)
	{
		int ret = 0, cur = rt;
		while (1)
		{
			if (x < val[cur])
				cur = ch[cur][0];
			else
			{
				ret += siz[ch[cur][0]];
				if (x == val[cur])
				{
					splay(cur); 
					return ret + 1;
				}
				ret += cnt[cur];
				cur = ch[cur][1];
			}
		}
	}
	inline int xrank(int x)
	{
		int cur = rt;
		while (1)
		{
			if (ch[cur][0] && x <= siz[ch[cur][0]])
				cur = ch[cur][0];
			else
			{
				x -= cnt[cur] + siz[ch[cur][0]];
				if (x <= 0)
				{
					splay(cur);
					return val[cur];
				}
				cur = ch[cur][1];
			}
		}
	}
	inline int pre()
	{
		int cur = ch[rt][0];
		if (!cur)
			return cur;
		if (ch[cur][1])
			cur = ch[cur][1];
		splay(cur);
		return cur;
	}
	inline int last()
	{
		int cur = ch[rt][1];
		if (!cur)
			return cur;
		if (ch[cur][0])
			cur = ch[cur][0];
		splay(cur);
		return cur;
	}
	inline void del(int x)
	{
		rank(x);
		if (cnt[rt] > 1)
		{
			cnt[rt] --;
			updata(rt);
			return;
		}
		if (!ch[rt][0] && !ch[rt][1])
		{
			clear(rt);
			rt = 0;
			return; 
		}
		if (!ch[rt][0])
		{
			int cur = rt;
			rt = ch[rt][1];
			fa[rt] = 0;
			clear(cur);
			return;
		}
		if (!ch[rt][1])
		{
			int cur = rt;
			rt = ch[rt][0];
			fa[rt] = 0;
			clear(cur);
			return;
		}
		int cur = rt, k = pre();
		fa[ch[cur][1]] = k;
		ch[k][1] = ch[cur][1];
		clear(cur);
		updata(rt);
	}
}T;

int main()
{
	int n, opt, x;
	scanf("%d", &n);
	while (n --)
	{
		scanf("%d%d", &opt, &x);
		if (opt == 1)
			T.insert(x);
		if (opt == 2)
			T.del(x);
		if (opt == 3)
			printf("%d\n", T.rank(x));
		if (opt == 4)
			printf("%d\n", T.xrank(x));
		if (opt == 5)
			T.insert(x), printf("%d\n", T.val[T.pre()]), T.del(x);
		if (opt == 6)
			T.insert(x), printf("%d\n", T.val[T.last()]), T.del(x);
	}
	
	return 0;
}
//P3369 【模板】普通平衡树
2022/8/18 18:25
加载中...