线段树求调
  • 板块灌水区
  • 楼主Vitamin_B
  • 当前回复10
  • 已保存回复10
  • 发布时间2024/3/9 14:08
  • 上次更新2024/3/9 15:47:41
查看原帖
线段树求调
743373
Vitamin_B楼主2024/3/9 14:08

题面

给你一个长度为 nn 的数组 aa,现有如下三种操作:

  1. 1 L R x 将区间 L,RL,R 中所有数变成 x
  2. 2 L R x 将区间 L,RL,R 中所有数加上 x
  3. 3 L R 求区间 L,RL,R 中所有数的最大值

错误代码

# pragma GCC optimize("Ofast,no-stack-protector")

# pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

# include <bits/stdc++.h>

typedef long long ll;

using namespace std;

const ll inf = 1e18;

int n, q, l, r, op;

ll lazy1[100005], lazy2[400005], tr[400005], k, a[100005];

void build (int x, int l, int r) {

	if (l == r) {

		tr[x] = a[l];

		return ;

	}

	const int mid = l + r >> 1, L = x << 1, R = L | 1;

	build (L, l, mid), build (R, mid + 1, r);

	tr[x] = max (tr[L], tr[R]);

	return ;

}

void pushdown (int x, int l, int r) {

	if (lazy1[x] < inf)
		tr[l] = tr[r] = lazy1[x];

	tr[l] += lazy2[x], tr[r] += lazy2[x];

	lazy2[l] += lazy2[x], lazy2[r] += lazy2[x];

	lazy1[l] = lazy1[r] = lazy1[x];

	lazy1[x] = inf, lazy2[x] = 0;

	return ;

}

void change1 (int x, int l, int r, int left, int right) {

	if (l == left && r == right) {

		lazy2[x] = 0;

		tr[x] = lazy1[x] = k;

		return ;

	}

	const int mid = l + r >> 1, L = x << 1, R = L | 1;

	pushdown (x, L, R);

	if (mid < left)
		change1 (R, mid + 1, r, left, right);
	else if (mid >= right)
		change1 (L, l, mid, left, right);
	else
		change1 (L, l, mid, left, mid), change1 (R, mid + 1, r, mid + 1, right);

	tr[x] = max (tr[L], tr[R]);

	return ;

}

void change2 (int x, int l, int r, int left, int right) {

	if (l == left && r == right) {

		tr[x] += k, lazy2[x] += k;

		return ;

	}

	const int mid = l + r >> 1, L = x << 1, R = L | 1;

	pushdown (x, L, R);

	if (mid < left)
		change2 (R, mid + 1, r, left, right);
	else if (mid >= right)
		change2 (L, l, mid, left, right);
	else
		change2 (L, l, mid, left, mid), change2 (R, mid + 1, r, mid + 1, right);

	tr[x] = max (tr[L], tr[R]);

	return ;

}

ll find (int x, int l, int r, int left, int right) {
//	cout << l << '~' << r << ':' << tr[x] << '\n';
	if (l == left && r == right)
		return tr[x];

	const int mid = l + r >> 1, L = x << 1, R = L | 1;

	pushdown (x, L, R);

	if (mid < left)
		return find (R, mid + 1, r, left, right);

	if (mid >= right)
		return find (L, l, mid, left, right);

	return max (find (L, l, mid, left, mid), find (R, mid + 1, r, mid + 1, right));

}

int main () {

	freopen ("change.in", "r", stdin);

	freopen ("change.out", "w", stdout);

	ios::sync_with_stdio (0);

	cin.tie (0);

	cout.tie (0);

	cin >> n >> q;

	for (int i = 1; i <= n; ++ i)
		cin >> a[i];

	build (1, 1, n);

	while (q --) {

		cin >> op >> l >> r;

		if (op < 2)
			cin >> k, change1 (1, 1, n, l, r);
		else if (op < 3)
			cin >> k, change2 (1, 1, n, l, r);
		else
			cout << find (1, 1, n, l, r) << '\n';

	}

	return 0;

}
2024/3/9 14:08
加载中...