1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| using i64 = long long; const int MAXN = 2e5 + 10; struct Node { int l, r; i64 w, s, m, t1, t2; Node *ls, *rs;
void makeModifyTag(int x) { int len = this->r - this->l + 1; w = t1 = x; s = x * len; m = t1 = x; t2 = 0; }
void makeAddTag(int x) { int len = this->r - this->l + 1; w += x; m += x; s += len * x; if (t1 != LLONG_MAX) t1 += x; else t2 += x; } void pushdown() { if (t1 != LLONG_MAX) { ls->makeModifyTag(t1); rs->makeModifyTag(t1); t1 = LLONG_MAX; } else if (t2) { ls->makeAddTag(t2); rs->makeAddTag(t2); t2 = 0; } } void pushup() { w = max(ls->w, rs->w); m = min(ls->m, rs->m); s = ls->s + rs->s; }
bool InRange(int L, int R) { return (L <= l) && (r <= R); } bool OutofRange(int L, int R) { return (l > R) || (r < L); }
void update(int L, int R, int x, int op) { if (InRange(L, R)) { if (op == 1) makeModifyTag(x); else makeAddTag(x); } else if (!OutofRange(L, R)) { pushdown(); ls->update(L, R, x, op); rs->update(L, R, x, op); pushup(); } }
i64 queryMax(int L, int R) { if (InRange(L, R)) return w; else if (!OutofRange(L, R)) { pushdown(); return max(ls->queryMax(L, R), rs->queryMax(L, R)); } else return LLONG_MIN; } i64 queryMin(int L, int R) { if (InRange(L, R)) return m; else if (!OutofRange(L, R)) { pushdown(); return min(ls->queryMin(L, R), rs->queryMin(L, R)); } else return LLONG_MAX; }
i64 querySum(int L, int R) { if (InRange(L, R)) return s; else if (!OutofRange(L, R)) { pushdown(); return ls->querySum(L, R) + rs->querySum(L, R); } else return 0; } };
Node Mem[MAXN << 1], *pool = Mem;
Node *New(int L, int R) { auto u = pool++; u->l = L; u->r = R; u->t1 = LLONG_MAX; u->t2 = 0; if (L != R) { int M = (L + R) >> 1; u->ls = New(L, M); u->rs = New(M + 1, R); u->pushup(); } else { u->w = vec[L]; u->s = vec[L]; u->m = vec[L]; } return u; }
|