1. 程式人生 > 其它 >做題記錄 Luogu P2343

做題記錄 Luogu P2343

Luogu P2343 寶石管理系統

平衡樹水題

比 treap 模板還要弱

#include<bits/stdc++.h>
using namespace std;
#define maxn 80005 * 50
class fhqtreap
{
	private:
	long long ch[maxn][2], size[maxn], rnd[maxn], val[maxn], tot;
	public:
	long long cnt, root;
	void pushup(long long x)
	{
		size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;
		return;
	}
	long long newnode(long long v)
	{
		long long x = ++tot;
		ch[x][0] = 0;
		ch[x][1] = 0;
		val[x] = v;
		size[x] = 1;
		rnd[x] = rand() % 500000;
		return x;
	}
	void give(long long a, long long b)
	{
		ch[a][0] = ch[b][0];
		ch[a][1] = ch[b][1];
		size[a] = size[b];
		rnd[a] = rnd[b];
		val[a] = val[b];
		return;
	}
	long long merge(long long a, long long b)
	{
		if(!a || !b)
		{
			return  a + b;
		}
		if(rnd[a] < rnd[b])
		{
			ch[a][1] = merge(ch[a][1], b);
			pushup(a);
			return a;
		}
		else
		{
			ch[b][0] = merge(a, ch[b][0]);
			pushup(b);
			return b;
		}
	}
	void split(long long rt, long long v, long long &x, long long &y)
	{
		if(!rt)
		{
			x = 0;
			y = 0;
			return;
		}
		if(val[rt] <= v)
		{
			x = rt;
			split(ch[rt][1], v, ch[rt][1], y);
			pushup(x);
		}
		else
		{
			y = rt;
			split(ch[rt][0], v, x, ch[rt][0]);
			pushup(y);
		}
		return;
	}
	void del(long long &rt, long long v)
	{
		long long x = 0, y = 0, z = 0;
		split(rt, v, x, z);
		split(x, v - 1, x, y);
		y = merge(ch[y][0], ch[y][1]);
		rt = merge(merge(x, y), z);
		return;
	}
	void insert(long long &rt, long long v)
	{
		long long x = 0, y = 0, z = 0;
		split(rt, v, x, y);
		z = newnode(v);
		rt = merge(merge(x, z), y);
		return;
	}
	long long kth(long long rt, long long k)
	{
		while(rt)
		{
			//cout << rt << ":" << val[rt] << ":" << k << endl;
			if(size[ch[rt][1]] + 1 == k)
			{
				return val[rt];
			}
			if(k <= size[ch[rt][1]])
			{
				rt = ch[rt][1];
			}
			else
			{
				k = k - size[ch[rt][1]] - 1;
				rt = ch[rt][0];
			}
		}
	}
	long long rank(long long &rt, long long v)
	{
		long long x = 0, y = 0;
		split(rt, v - 1, x, y);
		long long ret = size[x] + 1;
		rt = merge(x, y);
		return ret;
	}
	long long pre(long long &rt, long long v)
	{
		long long x = 0, y = 0, z = 0;
		split(rt, v - 1, x, y);
		long long k = size[x];
		if(k == 0)
		{
			return -1;
		}
		split(y, v, y, z);
		if(size[y] > 1)
		{
			rt = merge(merge(x, y), z);
			return val[y];
		}
		long long ret = kth(x, k);
		rt = merge(merge(x, y), z);
		return ret;
	}
	long long succ(long long &rt, long long v)
	{
		long long x = 0, y = 0, z = 0;
		split(rt, v, x, y);
		if(size[y] == 0)
		{
			return -1;
		}
		split(x, v - 1, x, z);
		if(size[z] > 1)
		{
			rt = merge(merge(x, z), y);
			return val[z];
		}
		long long ret = kth(y, 1);
		rt = merge(merge(x, z), y);
		return ret;
	}
};
fhqtreap stone;
int main()
{
	//ios::sync_with_stdio(false);
	//cin.tie(0);
	//cout.tie(0);
	long long n, q, opt, x, ans = 0, sum, num1, num2, flag;
	cin >> n >> q;
	for(int i = 1; i <= n; i++)
	{
		cin >> x;
		stone.insert(stone.root, x);
	}
	for(long long i = 1; i <= q; i++)
	{
		cin >> opt >> x;
		if(opt == 1)
		{
			cout << stone.kth(stone.root, x) << endl;
		}
		else
		{
			stone.insert(stone.root, x);
		}
	}
	return 0;
}