线段树(区间修改)
struct Tag { void apply(Tag& v) {
}};
struct Info { void apply(Tag& v) {
} friend Info operator + (Info a, Info b) { Info res = a;
return res; }};
struct SegmentTree { vector<Info> info; vector<Tag> tag; int n; SegmentTree() : n(0) { } SegmentTree(int n_) { n = n_; info.assign(4 << __lg(n), Info()); tag.assign(4 << __lg(n), Tag()); } void build(int p, int l, int r, vector<Info> &v) { if (l == r) { info[p] = v[l]; return; } int mid = l + r >> 1; build(p << 1, l, mid, v); build(p << 1 | 1, mid + 1, r, v); push_up(p); } void apply(int p, Tag &v) { info[p].apply(v); tag[p].apply(v); } void push_up(int p) { info[p] = info[p << 1] + info[p << 1 | 1]; } void push_down(int p) { // if (!tag[p]) return; !!! apply(p << 1, tag[p]); apply(p << 1 | 1, tag[p]); tag[p] = Tag(); } void range_apply(int p, int l, int r, int x, int y, Tag &v) { if (l > y || r < x) { return; } if (l >= x && r <= y) { apply(p, v); return; } int mid = l + r >> 1; push_down(p); range_apply(p << 1, l, mid, x, y, v); range_apply(p << 1 | 1, mid + 1, r, x, y, v); push_up(p); } void range_apply(int l, int r, Tag &v) { return range_apply(1, 1, n, l, r, v); } void modify(int p, int l, int r, int x, Info& v) { if (l == r) { info[p] = v; return; } int mid = l + r >> 1; if (x <= mid) modify(p << 1, l, mid, x, v); else modify(p << 1 | 1, mid + 1, r, x, v); } void modify(int x, Info& v) { modify(1, 1, n, x, v); } Info range_query(int p, int l, int r, int x, int y) { if (l > y || r < x) { return Info(); } if (l >= x && r <= y) { return info[p]; } int mid = l + r >> 1; push_down(p); Info res = range_query(p << 1, l, mid, x, y) + range_query(p << 1 | 1, mid + 1, r, x, y); return res; } Info range_query(int l, int r) { return range_query(1, 1, n, l, r); }};