单点修改线段树通用板子
template<class Info>
class SegmentTree {
public:
#define l(p) (p << 1)
#define r(p) (p << 1 | 1)
int n;
vector<Info>info;
SegmentTree() : n(0) {};
SegmentTree(int _n) {
init(_n);
}
SegmentTree(vector<Info>_init) {
init(_init);
}
void init(int _n) {
init(vector<Info>(_n));
}
void init(vector<Info> _init) {
n = _init.size();
info.assign(n << 2, Info());
auto build = [&](auto self, int p, int l, int r) {
if (l == r) {
info[p] = _init[l];
return;
}
int mid = l + r >> 1;
self(self, l(p), l, mid);
self(self, r(p), mid + 1, r);
pushup(p);
};
build(build, 1, 1, n);
}
void pushup(int p) {
info[p] = info[l(p)] + info[r(p)];
}
void modify(int p, int pl, int pr, int x, const Info& v) {
if (pl == pr) {
info[p] = v;
return;
}
int mid = pl + pr >> 1;
if (x <= mid)modify(l(p), pl, mid, x, v);
else modify(r(p), mid + 1, pr, x, v);
pushup(p);
}
void modify(int p, const Info& v) {
modify(1, 1, n, p, v);
}
Info query(int L, int R, int p, int pl, int pr) {
if (pl > R || pr < L)return Info();
if (L <= pl && pr <= R)return info[p];
int mid = pl + pr >> 1;
return query(L, R, l(p), pl, mid) + query(L, R, r(p), mid + 1, pr);
}
Info query(int L, int R) {
return query(L, R, 1, 1, n);
}
#undef l(p)
#undef r(p)
};
struct Info {
};
Info operator+(Info a, Info b) {
}
orz