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
| #define l_ch u << 1 #define r_ch u << 1 | 1 template <typename intType> struct ZKWTr { int n; std::vector<u8> _log; std::vector<intType> tr, tag; std::vector<size_t> sz; ZKWTr(size_t size) { n = size; _log.assign(n + 1, 0); for (int i = 2; i < n + 1; i++) _log[i] = _log[i / 2] + 1; tr.assign(2 * n + 2, 0); tag.assign(2 * n + 2, 0); sz.assign(2 * n + 2, 1); for (int u = n - 1; u; u--) sz[u] = sz[l_ch] + sz[r_ch]; } void build(std::vector<intType> vec) { std::copy(vec.begin(), vec.end(), tr.begin() + n + 1); for (int u = n - 1; u; u--) tr[u] = tr[l_ch] + tr[r_ch]; } void push_up(int u) { if (!u) return; tr[u] = tr[l_ch] + tr[r_ch]; } void modify(int u, intType val) { tr[u] += sz[u] * val; tag[u] += val; } void push_down(int u) { if (tag[u]) { modify(l_ch, tag[u]); modify(r_ch, tag[u]); tag[u] = 0; } } intType query(int l, int r) { l += n, r += n + 1; for (int i = _log[n] + 1; i; i--) push_down(l >> i), push_down(r >> i); intType rst = 0; for (; l < r; l >>= 1, r >>= 1) { if (l & 1) rst += tr[l++]; if (r & 1) rst += tr[--r]; } return rst; } void update(int l, int r, intType val) { l += n, r += n + 1; for (int i = _log[n] + 1; i; i--) push_down(l >> i), push_down(r >> i); for (int u = 0, v = 0; l < r; l >>= 1, r >>= 1) { if (l & 1) u = l, modify(l++, val); if (r & 1) v = r, modify(--r, val); do push_up(u >>= 1); while (l == r and u); do push_up(v >>= 1); while (l == r and v); } } };
|