给你一个长度为 n 的数组 a,现有如下三种操作:
1 L R x 将区间 L,R 中所有数变成 x2 L R x 将区间 L,R 中所有数加上 x3 L R 求区间 L,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;
}