Luo Gu P3391 literary balanced tree treap or splay

URL: https://www.luogu.org/problem/P3391

Meaning of the questions:

A given number of columns, $ a_i = i $, the number of columns of flip maintenance interval, all inverted outputs the result.

answer:

A, treap solution:

Involved in section flipped $ treap $ solution can only be used irrotationality $ treap $, there will be no spin $ treap $ split into three sub-tree, namely the interval left between the sections right and then switching to the section marked marked sub-tree, in $ merge $ when the pass mark to the next, due to the $ merge $ when no other sub-tree mark next pass, so $ split $, they also pass under the first mark and then $ split $. Inorder tree traversal output balance must be original sequence, so in the end we just preorder, it is the result of the output.

AC Code:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
struct Treap
{
	int val[MAXN], son[MAXN][2], rnk[MAXN], size[MAXN];
	bool tag[MAXN];
	int sz;
	void init()
	{
		sz = 0;
	}
	void pushup(int x)
	{
		size[x] = size[son[x][0]] + size[son[x][1]] + 1;
	}
	void pushdown(int x)
	{
		if (tag[x])
		{
			tag[x] = 0;
			tag[son[x][0]] ^= 1;
			tag[son[x][1]] ^= 1;
			swap(son[x][0], son[x][1]);
		}
	}
	int _rand()
	{
		static int seed = 12345;
		return seed = int(seed * 482711ll % 2147483647);
	}
	void merge(int& rt, int a, int b)
	{
		if (!a || !b)
		{
			rt = a + b;
			return;
		}
		if (rnk[a] < rnk[b])
		{
			pushdown(a), rt = a;
			merge(son[rt][1], son[a][1], b);
		}
		else
		{
			pushdown(b), rt = b;
			merge(son[rt][0], a, son[b][0]);
		}
		pushup(rt);
	}
	void split_sz(int rt, int& a, int& b, int s)
	{
		if (rt == 0)
		{
			a = b = 0;
			return;
		}
		pushdown(rt);
		if (size[son[rt][0]] < s)
		{
			a = rt;
			split_sz(son[rt][1], son[a][1], b, s - size[son[a][0]] - 1);
		}
		else
		{
			b = rt;
			split_sz(son[rt][0], a, son[b][0], s);
		}
		pushup(rt);
	}
	void split_v(int rt, int& a, int& b, int v)
	{
		if (rt == 0)
		{
			a = b = 0;
			return;
		}
		pushdown(rt);
		if (val[a] <= v)
			a = rt, split_v(son[rt][1], son[a][1], b, v);
		else
			b = rt, split_v(son[rt][0], a, son[b][0], v);
		pushup(rt);
	}
	int newnode(int x)
	{
		int rt = ++sz;
		val[rt] = x;
		rnk[rt] = _rand();
		son[rt][0] = son[rt][1] = 0;
		size[rt] = 1;
		tag[rt] = 0;
		return rt;
	}
	void insert(int& rt, int v)
	{
		int x = 0, y = 0, n = newnode(v);
		split_v(rt, x, y, v);
		merge(x, x, n);
		merge(rt, x, y);
	}
	void rerverse(int& rt, int l, int r)
	{
		int x = 0, y = 0, z = 0;
		split_sz(rt, x, y, r);
		split_sz(x, x, z, l - 1);
		tag[z] ^= 1;
		merge(x, x, z);
		merge(rt, x, y);
	}
	void print(int rt)
	{
		pushdown(rt);
		if (son[rt][0])
			print(son[rt][0]);
		printf("%d ", val[rt]);
		if (son[rt][1])
			print(son[rt][1]);
	}
};
Treap tr;
int p = 0;
int main()
{
	tr.init();
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i)
		tr.insert(p, i);
	int l, r;
	for (int i = 1; i <= m; ++i)
	{
		scanf("%d%d", &l, &r);
		tr.rerverse(p, l, r);
	}
	tr.print(p);
	putchar('\n');
	return 0;
}

Two, splay solution:

$ $ Splay the solution is to put the left end point of the precursor to the root $ $ splay, rear-wheel drive $ splay the right point to the right of the $ root of his son, the son is apparently the root of the left need to flip range, marking can then splay when the first mark and then flip pass under it, output method with $ treap $.

AC Code:

// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
struct Splay
{
	int size[MAXN], val[MAXN], fa[MAXN];
	int num[MAXN], son[MAXN][2], sta[MAXN];
	bool tag[MAXN];
	int sz, rt;
	void init()
	{
		rt = sz = 0;
	}
	void up(int x)
	{
		if (x)
		{
			size[x] = num[x];
			if (son[x][0])
				size[x] += size[son[x][0]];
			if (son[x][1])
				size[x] += size[son[x][1]];
		}
	}
	void down(int x)
	{
		if (tag[x])
		{
			tag[x] = 0;
			tag[son[x][0]] ^= 1;
			tag[son[x][1]] ^= 1;
			swap(son[x][0], son[x][1]);
		}
	}
	void con(int x, int y, int z)
	{
		if (x)
			fa[x] = y;
		if (y)
			son[y][z] = x;
	}
	int getson(int x)
	{
		return son[fa[x]][1] == x;
	}
	void rotate(int x)
	{
		int fx = fa[x], ffx = fa[fx];
		int fs = getson(x), ffs = getson(fx);
		con(son[x][fs ^ 1], fx, fs);
		con(fx, x, fs ^ 1);
		con(x, ffx, ffs);
		up(fx), up(x);
	}
	void splay(int x, int end)
	{
		end = fa[end];
		int top = 0;
		for (int f = x; f; f = fa[f])
			sta[++top] = f;
		for (int i = top; i; --i)
			down(sta[i]);
		int f;
		while (fa[x] != end)
		{
			f = fa[x];
			if (fa[f] != end)
				rotate(getson(x) == getson(f) ? f : x);
			rotate(x);
		}
		if (!end)
			rt = x;
	}
	int newnode(int x, int f)
	{
		int root = ++sz;
		val[root] = x;
		size[root] = num[root] = 1;
		son[root][0] = son[root][1] = 0;
		fa[root] = f;
		son[f][x > val[f]] = root;
		tag[root] = 0;
		return root;
	}
	void insert(int x)
	{
		if (!rt)
		{
			rt = newnode(x, 0);
			return;
		}
		int now = rt, f = 0;
		while (1)
		{
			if (x == val[now])
			{
				++num[now];
				up(now), up(f);
				splay(now, rt);
				return;
			}
			f = now, now = son[now][x > val[now]];
			if (!now)
			{
				int tmp = newnode(x, f);
				up(f);
				splay(tmp, rt);
				return;
			}
		}
	}
	int querynum(int rnk)
	{
		int ans = 0, now = rt;
		while (1)
		{
			down(now);
			if (son[now][0] && rnk <= size[son[now][0]])
			{
				now = son[now][0];
				continue;
			}
			if (son[now][0])
				rnk -= size[son[now][0]];
			if (rnk <= num[now])
			{
				splay(now, rt);
				return now;
			}
			rnk -= num[now];
			now = son[now][1];
			
		}
	}
	void reverse(int ql, int qr)
	{
		int l = querynum(ql), r = querynum(qr + 2);
		splay(l, rt), splay(r, son[l][1]);
		tag[son[r][0]] ^= 1;
	}
	void print(int x,int n)
	{
		down(x);
		if (son[x][0])
			print(son[x][0], n);
		if (val[x] > 1 && val[x] < n + 2)
			printf("%d ", val[x] - 1);
		if (son[x][1])
			print(son[x][1], n);
	}
};
Splay sp;
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n + 2; ++i)
		sp.insert(i);
	int l, r;
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d", &l, &r);
		sp.reverse(l, r);
	}
	sp.print(sp.rt, n);
	printf("\n");
	return 0;
}

  

Guess you like

Origin www.cnblogs.com/Aya-Uchida/p/11566735.html