7FA5 @ 2022-06-23 09:48:14
#include <bits/stdc++.h>
using namespace std;
struct tree
{
int l, r, value, lazy, s1, s2, flag;
tree()
{
lazy = -1;
value = 0;
s1 = s2 = 0;
}
};
int n, q, arr[1000005];
tree t[1000005];
void lazy1(int pos, int x)
{
t[pos].lazy = x;
t[pos].value = x;
t[pos].flag = 1;
return;
}
void lazy2(int pos, int x)
{
t[pos].lazy = x;
t[pos].value += x;
t[pos].flag = 2;
return;
}
void pushdown(int pos)
{
if (t[pos].flag == 1)
{
lazy1(t[pos].s1, t[pos].lazy);
lazy1(t[pos].s2, t[pos].lazy);
}
else
{
lazy2(t[pos].s1, t[pos].lazy);
lazy2(t[pos].s2, t[pos].lazy);
}
t[pos].lazy = -1;
return;
}
int build(int pos, int l, int r)
{
t[pos].l = l;
t[pos].r = r;
if (l == r)
{
t[pos].value = arr[l];
return t[pos].value;
}
t[pos].s1 = pos * 2;
t[pos].s2 = pos * 2 + 1;
t[pos].value = max(build(t[pos].s1, l, (l + r) / 2), build(t[pos].s2, (l + r) / 2 + 1, r));
return t[pos].value;
}
int update(int pos, int l, int r, int x, int f)
{
if (t[pos].lazy != -1)
pushdown(pos);
if (l <= t[pos].l && r >= t[pos].r)
{
if (f == 1)
lazy1(pos, x);
else
lazy2(pos, x);
return t[pos].value;
}
int mid = (t[pos].l + t[pos].r) / 2;
if (l <= mid || r <= mid)
update(t[pos].s1, l, r, x, f);
if (l > mid || r > mid)
update(t[pos].s2, l, r, x, f);
t[pos].value = max(t[t[pos].s1].value, t[t[pos].s2].value);
return t[pos].value;
}
int query(int pos, int l, int r)
{
if (t[pos].lazy != -1)
pushdown(pos);
if (l <= t[pos].l && r >= t[pos].r)
return t[pos].value;
int mid = (t[pos].l + t[pos].r) / 2, maxx = -0x7ffffff;
if (l <= mid || r <= mid)
maxx = max(maxx, query(t[pos].s1, l, r));
if (l >= mid || r > mid)
maxx = max(maxx, query(t[pos].s2, l, r));
t[pos].value = max(t[t[pos].s1].value, t[t[pos].s2].value);
return maxx;
}
int main()
{
int i;
cin >> n >> q;
for (i = 1; i <= n; i++)
cin >> arr[i];
build(1, 1, n);
for (i = 1; i <= q; i++)
{
int op, l, r, x;
cin >> op;
if (op != 3)
{
cin >> l >> r >> x;
update(1, l, r, x, op);
}
else
{
cin >> l >> r;
cout << query(1, l, r) << endl;
}
}
return 0;
}