线段树求调
查看原帖
线段树求调
602171
Ian_NIE楼主2025/6/12 22:08
#include <iostream>
#define int long long
using namespace std;

int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	while(!isdigit(ch))
	{
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while(isdigit(ch))
		x = x * 10 + ch - '0', 
		ch = getchar();
	return x * f;
}

const int MAXN = 1e6 + 6;
int n, q, op, l, r, x, a[MAXN], f1[MAXN << 2], f2[MAXN << 2], tr[MAXN << 2];
// f1表示直接推平的,f2表示在推平之后继续加上的 

void build(int x, int l, int r)
{
	f1[x] = -1, f2[x] = 0;
	if(l == r)
	{
		tr[x] = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build(x << 1, l, mid);
	build(x << 1 | 1, mid + 1, r);
	tr[x] = max(tr[x << 1], tr[x << 1 | 1]);
	return ;
}
void push_down(int x, int l, int r)
{
	int mid = l + r >> 1;
	if(f1[x] == -1)
	{ // 没有推平 
		tr[x << 1] += f2[x], tr[x << 1 | 1] += f2[x];
		f2[x << 1] += f2[x], f2[x << 1 | 1] += f2[x];
		f2[x] = 0;
	}
	if(f1[x] != -1)
	{ // 存在推平 
		tr[x << 1] = f1[x] + f2[x], tr[x << 1 | 1] = f1[x] + f2[x];
		f1[x << 1] = f1[x], f1[x << 1 | 1] = f1[x];
		f2[x << 1] = f2[x], f2[x << 1] = f2[x]; 
	}
}
void update1(int x, int l, int r, int ql, int qr, int k)
{
	if(ql <= l && r <= qr)
	{
		f1[x] = k, f2[x] = 0, tr[x] = k;
		return ;
	}
	push_down(x, l, r);
	int mid = l + r >> 1;
	if(ql <= mid) update1(x << 1, l, mid, ql, qr, k);
	if(qr > mid) update1(x << 1 | 1, mid + 1, r, ql, qr, k);
	tr[x] = max(tr[x << 1], tr[x << 1 | 1]);
	return ;
}
void update2(int x, int l, int r, int ql, int qr, int k)
{
	if(ql <= l && r <= qr)
	{
		f2[x] += k, tr[x] += k;
		return ;
	}
	push_down(x, l, r);
	int mid = l + r >> 1;
	if(ql <= mid) update1(x << 1, l, mid, ql, qr, k);
	if(qr > mid) update2(x << 1 | 1, mid + 1, r, ql, qr, k);
	tr[x] = max(tr[x << 1], tr[x << 1 | 1]);
	return ;
}
int calc(int x, int l, int r, int ql, int qr)
{
	if(ql <= l && r <= qr) return tr[x];
	push_down(x, l, r);
	int mid = l + r >> 1, res = -9e18;
	if(ql <= mid) res = max(res, calc(x << 1, l, mid, ql, qr));
	if(qr > mid) res = max(res, calc(x << 1 | 1, mid + 1, r, ql, qr));
	return res;
}

signed main(signed argc, char** argv)
{
	n = read(), q = read();
	for(int i = 1; i <= n; i++) a[i] = read();
	build(1, 1, n); 
	while(q--)
	{
		cin >> op;
		if(op == 1)
		{
			cin >> l >> r >> x;
			update1(1, 1, n, l, r, x);
		}
		if(op == 2)
		{
			cin >> l >> r >> x;
			update2(1, 1, n, l, r, x);
		}
		if(op == 3)
		{
			cin >> l >> r;
			cout << calc(1, 1, n, l, r) << endl;
		}
	}
	
	return 0;
}

死透了20求调

2025/6/12 22:08
加载中...