LG P4146 序列终结者

( ext{Problem})

支持区间加区间翻转区间最大值

( ext{Solution})

( ext{FHQ-Treap}) 两个标记加与翻转
然后维护区间最大值

( ext{Code})

#include <cstdio>
#include <algorithm>
#include <ctime>
#define re register
using namespace std;

const int N = 5e4 + 5;
int n, m, rt;
int ls[N], rs[N], mx[N], val[N], siz[N], tag1[N], tag2[N], rnd[N];

inline void read(int &x)
{
	x = 0; int f = 1; char ch = getchar();
	while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : f), ch = getchar();
	while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
	x *= f;
}

inline int new_node(int v)
{
	static int size = 0;
	val[++size] = v, mx[size] = v, siz[size] = 1, rnd[size] = rand(),
	ls[size] = rs[size] = tag1[size] = tag2[size] = 0;
	return size;
}

inline void pushup(int p)
{
	siz[p] = siz[ls[p]] + siz[rs[p]] + 1, mx[p] = val[p];
	if (ls[p]) mx[p] = max(mx[p], mx[ls[p]]);
	if (rs[p]) mx[p] = max(mx[p], mx[rs[p]]);
}

inline void pushdown(int p)
{
	if (!p) return;
	if (tag1[p])
	{
		if (ls[p]) tag1[ls[p]] += tag1[p], mx[ls[p]] += tag1[p], val[ls[p]] += tag1[p];
		if (rs[p]) tag1[rs[p]] += tag1[p], mx[rs[p]] += tag1[p], val[rs[p]] += tag1[p]; 
		tag1[p] = 0;
	}
	if (tag2[p])
	{
		tag2[p] = 0, swap(ls[p], rs[p]);
		if (ls[p]) tag2[ls[p]] ^= 1;
		if (rs[p]) tag2[rs[p]] ^= 1;
	}
}

void split(int p, int k, int &x, int &y)
{
	if (!p) return void(x = y = 0);
	pushdown(p);
	if (k <= siz[ls[p]]) y = p, split(ls[p], k, x, ls[y]);
	else x = p, split(rs[p], k - siz[ls[p]] - 1, rs[x], y);
	pushup(p);
}

int merge(int x, int y)
{
	if (!x || !y) return x | y;
	pushdown(x), pushdown(y);
	if (rnd[x] < rnd[y]){rs[x] = merge(rs[x], y), pushup(x); return x;}
	ls[y] = merge(x, ls[y]), pushup(y); return y;
}

int main()
{
	srand((unsigned)time(NULL));
	read(n), read(m);
	for(re int i = 1; i <= n; i++) rt = merge(rt, new_node(0));
	for(re int i = 1, op, l, r, ad, x, y, u, v; i <= m; i++)
	{
		read(op), read(l), read(r);
		split(rt, r, x, y), split(x, l - 1, u, v);
		if (op == 1) read(ad), tag1[v] += ad, mx[v] += ad, val[v] += ad;
		else if (op == 2) tag2[v] ^= 1;
		else printf("%d
", mx[v]);
		rt = merge(merge(u, v), y);
	}
}
原文地址:https://www.cnblogs.com/leiyuanze/p/15041401.html