我口胡的 splay
查看原帖
我口胡的 splay
482728
Engulf楼主2022/7/12 18:23

10pts,RE + TLE https://www.luogu.com.cn/record/79255860

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 500005;
int n, m;
int root, idx;
int a[N];
struct Node
{
	int son[2], val, fa, siz;
	int sum, ml, mr, mx;
	int rev, cov;
	#define ls(x) (tr[x].son[0])
	#define rs(x) (tr[x].son[1])
	#define val(x) (tr[x].val)
	#define fa(x) (tr[x].fa)
	#define siz(x) (tr[x].siz)
	#define sum(x) (tr[x].sum)
	#define ml(x) (tr[x].ml)
	#define mr(x) (tr[x].mr)
	#define mx(x) (tr[x].mx)
	#define rev(x) (tr[x].rev)
	#define cov(x) (tr[x].cov)
}tr[N];
int top, rub[N];

void recycle(int x)
{
	if (ls(x)) recycle(ls(x));
	if (rs(x)) recycle(rs(x));
	rub[ ++ top] = x;
}

int New(int val, int fa)
{
	int x = top ? rub[top -- ] : ++ idx;
	fa(x) = fa;
	val(x) = sum(x) = mx(x) = val;
	siz(x) = 1;
	ml(x) = mr(x) = max(val, 0LL);
	return x;
}
void pushup(int x)
{
	siz(x) = siz(ls(x)) + siz(rs(x)) + 1;
	sum(x) = sum(ls(x)) + sum(rs(x)) + val(x);
	ml(x) = max(ml(ls(x)), sum(ls(x)) + val(x) + ml(rs(x)));
	mr(x) = max(mr(rs(x)), sum(rs(x)) + val(x) + mr(ls(x)));
	mx(x) = max( {mx(ls(x)), mx(rs(x)), mr(ls(x)) + val(x) + ml(rs(x))} );
}
void pushdown(int x)
{
	if (rev(x))
	{
		if (ls(x)) rev(ls(x)) ^= 1, swap(ml(ls(x)), mr(ls(x))), swap(ls(ls(x)), rs(ls(x)));
		if (rs(x)) rev(rs(x)) ^= 1, swap(ml(rs(x)), mr(rs(x))), swap(ls(rs(x)), rs(rs(x)));		
		rev(x) ^= 1;
	}
	if (cov(x))
	{
		if (ls(x)) sum(ls(x)) = val(x) * siz(ls(x)), cov(ls(x)) = 1, val(ls(x)) = val(x);
		if (rs(x)) sum(rs(x)) = val(x) * siz(rs(x)), cov(rs(x)) = 1, val(rs(x)) = val(x);
		if (val(x) > 0)
		{
			if (ls(x)) ml(ls(x)) = mr(ls(x)) = mx(ls(x)) = sum(ls(x));
			if (rs(x)) ml(rs(x)) = mr(rs(x)) = mx(rs(x)) = sum(rs(x));
		}
		else
		{
			if (ls(x)) ml(ls(x)) = mr(ls(x)) = 0, mx(ls(x)) = val(x);
			if (rs(x)) ml(rs(x)) = mr(rs(x)) = 0, mx(rs(x)) = val(x);
		}
		cov(x) = 0;
	}
}
void rotate(int x)
{
	int y = fa(x), z = fa(y);
	pushdown(y), pushdown(x);
	int k = rs(y) == x;
	fa(x) = z, tr[z].son[rs(z) == y] = x;
	tr[y].son[k] = tr[x].son[k ^ 1], fa(tr[x].son[k ^ 1]) = y;
	tr[x].son[k ^ 1] = y, fa(y) = x;
	pushup(y), pushup(x);
}
void splay(int x, int goal)
{
	while (fa(x) != goal)
	{
		int y = fa(x), z = fa(y);
		if (z != goal)
			if ((rs(z) == y) ^ (rs(y) == x)) rotate(x);
			else rotate(y);
		rotate(x);
	}
	if (!goal) root = x;
}
int get(int k)
{
	int x = root;
	while (114514)
	{
		pushdown(x);
		if (siz(ls(x)) >= k) x = ls(x);
		else if (siz(ls(x)) + 1 >= k) return x;
		else k -= siz(ls(x)) + 1, x = rs(x);
	}
}
void reverse(int l, int r)
{
	int x = get(l - 1), y = get(r + 1);
	splay(x, 0), splay(y, x);
	rev(ls(y)) ^= 1;
	swap(ml(ls(y)), mr(ls(y)));
	swap(ls(ls(y)), rs(ls(y)));
	pushup(y), pushup(x);
}
void remove(int l, int r)
{
	int x = get(l - 1), y = get(r + 1);
	splay(x, 0), splay(y, x);
	recycle(ls(y));
	ls(y) = 0;
	pushup(y), pushup(x);
}
void cover(int l, int r, int val)
{
	int x = get(l - 1), y = get(r + 1);
	splay(x, 0), splay(y, x);
	int t = ls(y);
	val(t) = val, sum(t) = siz(t) * val, cov(t) = 1;
	if (val > 0) ml(t) = mr(t) = mx(t) = sum(t);
	else ml(t) = mr(t) = 0, mx(t) = val;
	pushup(y), pushup(x);
}
void build(int &x, int l, int r, int fa)
{
	if (l > r) return;
	int mid = l + r >> 1;
	x = New(a[mid], fa);
	build(ls(x), l, mid - 1, x);
	build(rs(x), mid + 1, r, x);
	pushup(x);
}
void insert(int x, int tot)
{
	for (int i = 1; i <= tot; i ++ ) cin >> a[i];
	int rt = 0;
	build(rt, 1, tot, 0);
	int l = get(x), r = get(x + 1);
	splay(l, 0), splay(r, l);
	ls(r) = rt, fa(rt) = r;
	pushup(r), pushup(l);
}
int q_sum(int l, int r)
{
	int x = get(l - 1), y = get(r + 1);
	splay(x, 0), splay(y, x);
	return sum(ls(y));
}
int q_max()
{
	return mx(root);
}

signed main()
{
	ios_base::sync_with_stdio(false), cin.tie(nullptr);
	cin >> n >> m;
	a[1] = a[n] = mx(0) = LLONG_MIN;
	n += 2;
	for (int i = 2; i < n; i ++ ) cin >> a[i];
	build(root, 1, n, 0);
	while (m -- )
	{
		string s;
		int pos, tot;
		cin >> s;
		if (s == "INSERT")
		{
			cin >> pos >> tot;
			++ pos;
			insert(pos, tot);
		}
		if (s == "DELETE")
		{
			cin >> pos >> tot;
			++ pos;
			remove(pos, pos + tot - 1);
		}
		if (s == "MAKE-SAME")
		{
			int c;
			cin >> pos >> tot >> c;
			++ pos;
			cover(pos, pos + tot - 1, c);
		}
		if (s == "REVERSE")
		{
			cin >> pos >> tot;
			++ pos;
			reverse(pos, pos + tot - 1);
		}
		if (s == "GET-SUM")
		{
			cin >> pos >> tot;
			++ pos;
			cout << q_sum(pos, pos + tot - 1) << '\n';
		}
		if (s == "MAX-SUM")
		{
			cout << q_max() << '\n';
		}
	}
	return 0;
}
2022/7/12 18:23
加载中...