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
| class SegTree { private: void push_up(int pos) { f[pos].v = f[ls(pos)].v + f[rs(pos)].v; } inline void push_down(long long pos) { if (!f[pos].t) return; f[ls(pos)].t += f[pos].t; f[rs(pos)].t += f[pos].t; int mid = (f[pos].l + f[pos].r) / 2; f[ls(pos)].v += f[pos].t * (mid - f[ls(pos)].l + 1); f[rs(pos)].v += f[pos].t * (f[rs(pos)].r - mid); f[pos].t = 0; }
public: long long query(int pos, int l, int r) { push_down(pos); if (f[pos].l >= l && f[pos].r <= r) return f[pos].v; int mid = (f[pos].l + f[pos].r) / 2; if (l > mid) return query(rs(pos), l, r); else if (r <= mid) return query(ls(pos), l, r); else return query(ls(pos), l, mid) + query(rs(pos), mid + 1, r); } void update(int pos, int l, int r, long long k) { if (f[pos].l >= l && f[pos].r <= r) { f[pos].t += k; f[pos].v += k * (r - l + 1); return; } push_down(pos); int mid = (f[pos].l + f[pos].r) / 2; if (l > mid) update(rs(pos), l, r, k); else if (r <= mid) update(ls(pos), l, r, k); else update(ls(pos), l, mid, k), update(rs(pos), mid + 1, r, k); push_up(pos); }
struct node { long long l, r, v, t; }; long long *a;
SegTree(long long s, long long *ori) { this->size = s; a = ori; f = (node *)malloc((s * 4 + 10) * sizeof(node)); build(1, 1, s); }
private: int size = 1e6 + 5; node *f; inline int ls(int p) { return p << 1; } inline int rs(int p) { return p << 1 | 1; }
void build(int pos, int l, int r) { f[pos] = {l, r, 0, 0}; if (l == r) { f[pos].v = a[l]; return; } int mid = ((l + r) >> 1); build(ls(pos), l, mid); build(rs(pos), mid + 1, r); push_up(pos); } };
|