Splay 4pts TLE求调
查看原帖
Splay 4pts TLE求调
738378
TJHtjh楼主2025/6/13 12:53
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef unsigned int UINT;
typedef unsigned long long ULL;

typedef pair<int, int> PII;
#define x first
#define y second

#define pb push_back

const int N = 1e5 + 5;
int n, m;

namespace Splay
{
	int rt, idx;
	int fa[N], son[N][2];
	int val[N], cnt[N];
	int sz[N];
	
	bool Dir(int x)
	{
		return x == son[fa[x]][1];
	}
	
	void PushUp(int x)
	{
		sz[x] = sz[son[x][0]] + sz[son[x][1]] + cnt[x];
	}
	
	void Rotate(int x)
	{
		int y = fa[x], z = fa[y];
		int w = Dir(x);
		
		son[y][w] = son[x][!w], son[x][!w] = y;
		if (z) son[z][Dir(y)] = x;
		if (son[y][w]) fa[son[y][w]] = y;
		fa[y] = x, fa[x] = z;

		PushUp(y), PushUp(x);
	}
	
	void Splay(int &z, int x)
	{
		int w = fa[z];
		for (int y; (y = fa[x]) != w; Rotate(x))
			if (fa[y] != w)
				Rotate(Dir(x) == Dir(y) ? y : x);
		z = x;
	}
	
	void Find(int &z, int v)
	{
		int x = z, y = fa[x];
		for ( ; x && val[x] != v; x = son[y = x][v > val[x]]);
		Splay(z, x ? x : y);
	}
	
	void Loc(int &z, int k)
	{
		int x = z;
		for ( ; ; )
		{
			if (sz[son[x][0]] >= k) x = son[x][0];
			else if (sz[son[x][0]] + cnt[x] >= k) break;
			else
			{
				k -= sz[son[x][0]] + cnt[x];
				x = son[x][1];
			}
		}
		Splay(z, x);
	}
	
	int FindKth(int k) 
	{
		if (k > sz[rt]) return -1;
		Loc(rt, k);
		return val[rt];
	}
	
	int Merge(int x, int y) 
	{
		if (!x || !y) return x | y;
		Loc(y, 1);
		son[y][0] = x, fa[x] = y;
		PushUp(y);
		return y;
	}
	
	void Insert(int v)
	{
		int x = rt, y = 0;
		for ( ; x && val[x] != v; x = son[y = x][v > val[x]]);
		
		if (x)
			cnt[x] ++ , sz[x] ++ ;
		else
		{
			x = ++ idx;
			val[x] = v, cnt[x] = 1;
			sz[x] = 1;
			fa[x] = y;
			if (y) son[y][v > val[y]] = x;
		}
		Splay(rt, x);
	}
	
	bool Remove(int v)
	{
		Find(rt, v);
		if (!rt || val[rt] != v) return false;
		cnt[rt] -- , sz[rt] -- ;
		if (!cnt[rt]) 
		{
			int x = son[rt][0], y = son[rt][1];
			fa[x] = fa[y] = 0;
			rt = Merge(x, y);
		}
		return true;
	}
	
	int FindRank(int v)
	{
		Find(rt, v);
		return sz[son[rt][0]] + (val[rt] < v ? cnt[rt] : 0) + 1;
	}
	
	int FindPrev(int v) 
	{
		Find(rt, v);
		if (rt && val[rt] < v) return val[rt];
		
		int x = son[rt][0];
		if (!x) return -1;
		for ( ; son[x][1]; x = son[x][1]);
		Splay(rt, x);
		return val[rt];
	}
	
	int FindNext(int v) 
	{
		Find(rt, v);
		if (rt && val[rt] > v) return val[rt];
		
		int x = son[rt][1];
		if (!x) return -1;
		for ( ; son[x][0]; x = son[x][0]);
		Splay(rt, x);
		return val[rt];
	}
}
using namespace Splay;

signed main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i ++ )
	{
		int x; scanf("%d", &x);
		Insert(x);
	}
	
	int res = 0, last = 0;
	while (m -- )
	{
		int opt, x; scanf("%d%d", &opt, &x);
		x ^= last;
		
		if (opt == 1)
			Insert(x);
		else if (opt == 2)
			Remove(x);
		else if (opt == 3)
		{
			last = FindRank(x);
			res ^= last;
		}
		else if (opt == 4)
		{
			last = FindKth(x);
			res ^= last;
		}
		else if (opt == 5)
		{
			last = FindPrev(x);
			res ^= last;
		}
		else
		{
			last = FindNext(x);
			res ^= last;
		}
	}
	printf("%d\n", res);

    return 0;
}

2025/6/13 12:53
加载中...