线段树维护,三个lazy数组表示这个区间分别有个从右到左,全部,从左到右的数据覆盖。
#include
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N = 5e5 + 10;
int lazy[N * 6][3], c[N * 6];
void pushup(int rt) {
c[rt] = max(c[rt << 1], c[rt << 1 | 1]);
}
void pushdown(int l,int r,int rt) {
int m = (l + r) >> 1;
if (lazy[rt][0]) {
int t = lazy[rt][0];
lazy[rt << 1][0] = max(lazy[rt << 1][0], t);
lazy[rt << 1 | 1][0] = max(lazy[rt << 1 | 1][0], t - (m - l + 1));
}
if (lazy[rt][1]) {
int t = lazy[rt][1];
lazy[rt << 1][1] = max(lazy[rt << 1][1], t);
lazy[rt << 1 | 1][1] = max(lazy[rt << 1 | 1][1], t);
}
if (lazy[rt][2]) {
int t = lazy[rt][2];
lazy[rt << 1][2] = max(lazy[rt << 1][2], t - (r - m));
lazy[rt << 1 | 1][2] = max(lazy[rt << 1 | 1][2], t);
}
c[rt << 1] = max(c[rt << 1], max(lazy[rt << 1][0],
max(lazy[rt << 1][1], lazy[rt << 1][2])));
c[rt << 1 | 1] = max(c[rt << 1 | 1], max(lazy[rt << 1 | 1][0],
max(lazy[rt << 1 | 1][1], lazy[rt << 1 | 1][2])));
}
void change(int l, int r, int rt, int L, int R, int x,int type) {
if (L <= l && r <= R) {
lazy[rt][type] = max(lazy[rt][type], x);
c[rt] = max(c[rt], lazy[rt][type]);
return;
}
pushdown(l, r, rt);
int m = (l + r) >> 1;
if (type == 1) {
if (L <= m) {
change(lson, L, R, x, type);
}
if (R > m) {
change(rson, L, R, x, type);
}
}
else if (type == 0) {
if (L <= m) {
change(lson, L, R, x, type);
}
if (R > m) {
if (L <= m) {
change(rson, L, R, x - (m - L + 1), type);
}
else {
change(rson, L, R, x, type);
}
}
}
else {
if (L <= m) {
if (R > m) {
change(lson, L, R, x - (R - m), type);
}
else {
change(lson, L, R, x, type);
}
}
if (R > m) {
change(rson, L, R, x, type);
}
}
pushup(rt);
}
int query(int l, int r, int rt,int L,int R) {
int ans = 0;
if (L <= l && r <= R) {
return c[rt];
}
int m = (l + r) >> 1;
pushdown(l, r, rt);
if (L <= m) {
ans = max(ans, query(lson, L, R));
}
if (R > m) {
ans = max(ans, query(rson, L, R));
}
return ans;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, q;
cin >> n >> q;
while (q--) {
int a, b, c, d;
cin >> d >> a >> b;
if (d == 1) {
cin >> c;
change(1, n, 1, a, b, c, 1);
if (a != 1 && c != 1) {
change(1, n, 1, 1, a - 1, c - 1, 2);
}
if (b != n && c != 1) {
change(1, n, 1, b + 1, n, c - 1, 0);
}
}
else {
cout << query(1, n, 1, a, b) << "\n";
}
}
return 0;
}
/*
1 2 3 4 5
3 5 7 9
*/