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
| class SegmentTree { private final int n; private final long[] t, z;
public SegmentTree(int[] a) { n = a.length; t = new long[4 * n]; z = new long[4 * n]; build(a, 1, 1, n); }
private void build(int[] a, int i, int l, int r) { if (l == r) { t[i] = a[l - 1]; return; } int mid = l + (r - l) / 2; build(a, 2 * i, l, mid); build(a, 2 * i + 1, mid + 1, r); t[i] = t[2 * i] + t[2 * i + 1]; }
private void lazy(int i, int lo, int hi, long k) { t[i] += k * (hi - lo + 1); z[i] += k; }
private void down(int i, int lo, int hi) { if (z[i] == 0) { return; } int mid = lo + (hi - lo) / 2; lazy(2 * i, lo, mid, z[i]); lazy(2 * i + 1, mid + 1, hi, z[i]); z[i] = 0; }
public void add(int l, int r, int k) { if (l > r) return; add(1, 1, n, l, r, k); }
private void add(int i, int lo, int hi, int l, int r, int k) { if (lo >= l && hi <= r) { lazy(i, lo, hi, k); return; } down(i, lo, hi); int mid = lo + (hi - lo) / 2; if (l <= mid) add(2 * i, lo, mid, l, r, k); if (r > mid) add(2 * i + 1, mid + 1, hi, l, r, k); t[i] = t[2 * i] + t[2 * i + 1]; }
public long get(int l, int r) { if (l > r) return 0L; return get(1, 1, n, l, r); }
private long get(int i, int lo, int hi, int l, int r) { if (lo >= l && hi <= r) { return t[i]; } down(i, lo, hi); long res = 0L; int mid = lo + (hi - lo) / 2; if (l <= mid) res += get(2 * i, lo, mid, l, r); if (r > mid) res += get(2 * i + 1, mid + 1, hi, l, r); return res; } }
|