蒟蒻求助fhq-treap
查看原帖
蒟蒻求助fhq-treap
519384
Link_Cut_Y楼主2022/1/27 12:25
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 50010;
int n, m;
int root, idx;
int x, y, z;

struct Tree
{
	int s[2], size, v;
	int dat;
	int add, rev;
	int maxn;
}tr[N];

void pushup(int u)
{
	tr[u].size = tr[tr[u].s[0]].size + tr[tr[u].s[1]].size + 1;
	tr[u].maxn = max(tr[tr[u].s[1]].maxn, tr[tr[u].s[0]].maxn);
}

void pushdown(int u)
{
	if (tr[u].add)
	{
		tr[tr[u].s[0]].v += tr[u].add, tr[tr[u].s[1]].v += tr[u].add;
		tr[tr[u].s[0]].add += tr[u].add, tr[tr[u].s[1]].add += tr[u].add;
		tr[tr[u].s[0]].maxn += tr[u].add, tr[tr[u].s[1]].maxn += tr[u].add;
		tr[u].add = 0;
	}
	if (tr[u].rev)
	{
		swap(tr[u].s[0], tr[u].s[1]);
		tr[tr[u].s[0]].rev ^= 1, tr[tr[u].s[1]].rev ^= 1;
		tr[u].rev = 0;
	}
}

void split(int u, int sz, int &x, int &y)
{
	if (!u) x = y = 0;
	else
	{
		pushdown(u);
		
		if (tr[tr[u].s[0]].size + 1 <= sz) x = u, split(tr[u].s[1], sz - tr[tr[u].s[0]].size - 1, tr[u].s[1], y);
		else y = u, split(tr[u].s[0], sz, x, tr[u].s[0]);
		
		pushup(u);
	}
}

int merge(int a, int b)
{
	if (!a || !b) return a + b;
	if (tr[a].dat < tr[b].dat)
	{
		pushdown(a);
		tr[a].s[1] = merge(tr[a].s[1], b);
		pushup(a);
		return a;
	}
	
	else
	{
		pushdown(b);
		tr[b].s[0] = merge(a, tr[b].s[0]);
		pushup(b);
		return b;
	}
}

void insert(int v)
{
	tr[ ++ idx].v = v, tr[idx].size = 1, tr[idx].dat = rand(), tr[idx].maxn = v;
	root = merge(root, idx);
}

void reverse_interval(int l, int r)
{
	split(root, l - 1, x, y), split(y, r - l + 1, y, z);
	tr[y].rev ^= 1;
	root = merge(x, merge(y, z));
}

void add_interval(int l, int r, int v)
{
	split(root, l - 1, x, y), split(y, r - l + 1, y, z);
	tr[y].add += v;
	tr[y].maxn += v;
	root = merge(x, merge(y, z));
}

int query(int l, int r)
{
	split(root, l - 1, x, y), split(y, r - l + 1, y, z);
	int res = tr[y].maxn;
	root = merge(x, merge(y, z));
	return res;
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i ++ ) insert(0);
	
	while (m -- )
	{
		int opt, l, r, v;
		scanf("%d%d%d", &opt, &l, &r);
		if (opt == 1)
		{
			scanf("%d", &v);
			add_interval(l, r, v);
		}
		else if (opt == 2) reverse_interval(l, r);
		else printf("%d\n", query(l, r));
	}
	
	return 0;
}
2022/1/27 12:25
加载中...