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
| struct Info { int len; i64 sum; };
struct Tag { i64 add; };
Info operator + (const Info& l, const Info& r) { return {l.len + r.len, l.sum + r.sum}; }
Info operator + (const Info& v, const Tag& t) { return {v.len, v.sum + t.add * v.len}; }
Tag operator + (const Tag& t1, const Tag& t2) { return {t1.add + t2.add}; }
struct Node { Tag t; Info val; };
struct Segment_tree { int n; std::vector<Node> seg; std::vector<int> a; Segment_tree(int n) : n(n), seg(n * 4) {} void pushup(int id) { seg[id].val = seg[id << 1].val + seg[id << 1 | 1].val; }
void settag(int id, Tag t) { seg[id].val = seg[id].val + t; seg[id].t = seg[id].t + t; }
void pushdown(int id) { if (seg[id].t.add != 0) { settag(id << 1, seg[id].t); settag(id << 1 | 1, seg[id].t); seg[id].t.add = 0; } }
void init(std::vector<int>& b) { a = b; }
void build(int id, int l, int r) { if (l == r) { seg[id].val = {1, a[l]}; return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); pushup(id); }
void modify(int id, int l, int r, int ql, int qr, Tag t) { if (l == ql && r == qr) { settag(id, t); return; } pushdown(id); int mid = l + r >> 1; if (qr <= mid) modify(id << 1, l, mid, ql, qr, t); else if (ql >= mid + 1) modify(id << 1 | 1, mid + 1, r, ql, qr, t); else modify(id << 1, l, mid, ql, mid, t), modify(id << 1 | 1, mid + 1, r, mid + 1, qr, t); pushup(id); }
Info query(int id, int l, int r, int ql, int qr) { if (l == ql && r == qr) return seg[id].val; pushdown(id); int mid = l + r >> 1; if (qr <= mid) return query(id << 1, l, mid, ql, qr); else if (ql >= mid + 1) return query(id << 1 | 1, mid + 1, r, ql, qr); else return query(id << 1, l, mid, ql, mid) + query(id << 1 | 1, mid + 1, r, mid + 1, qr); } };
|