线段树模板
自用
v1
#include <bits/stdc++.h>
#define l(p) (p << 1)
#define r(p) (p << 1 | 1)
using namespace std;
using ll = long long;
constexpr int N = 1e5 + 7;
int n, m, add[N << 2]; ll sum[N << 2];
void psu(int p) { sum[p] = sum[l(p)] + sum[r(p)]; }
void psd(int p, int l, int r) {
if (add[p] && l != r) {
add[l(p)] += add[p], add[r(p)] += add[p];
int mid = (l + r) >> 1;
sum[l(p)] += add[p] * (mid - l + 1);
sum[r(p)] += add[p] * (r - mid);
add[p] = 0;
}
}
void upd(int p, int l, int r, int L, int R, ll x) {
if (l >= L && r <= R) {
add[p] += x, sum[p] += x * (r - l + 1);
return;
}
psd(p, l, r);
int mid = (l + r) >> 1;
if (L <= mid) upd(l(p), l, mid, L, R, x);
if (R > mid) upd(r(p), mid + 1, r, L, R, x);
psu(p);
}
ll ask(int p, int l, int r, int L, int R) {
if (l >= L && r <= R) return sum[p];
psd(p, l, r);
int mid = (l + r) >> 1; ll ans = 0;
if (L <= mid) ans += ask(l(p), l, mid, L, R);
if (R > mid) ans += ask(r(p), mid + 1, r, L, R);
return ans;
}
v2
#include <bits/stdc++.h>
using ll = long long;
constexpr ll inf = 1e18;
struct segtree {
int n;
std::vector<ll> ad, mx;
segtree(int sz) : ad((sz + 1) << 1), mx((sz + 1) << 1), n(sz) {}
std::function<ll(ll, ll)> root = [&](ll l, ll r) {
return l + r | l != r;
};
std::function<void(int, int, int)> pushup = [&](int l, int r, int mid) {
ll p = root(l, r), pl = root(l, mid), pr = root(mid + 1, r);
mx[p] = std::max(mx[pl], mx[pr]);
};
std::function<void(int, int)> pushdown = [&](int l, int r) {
if (l == r || ad[root(l, r)] == 0) {
return ;
}
ll mid = l + r >> 1;
ll p = root(l, r), pl = root(l, mid), pr = root(mid + 1, r);
ad[pl] += ad[p], ad[pr] += ad[p];
mx[pl] += ad[p], mx[pr] += ad[p];
ad[p] = 0;
};
std::function<void(int, ll)> modify = [&](int x, ll v) {
ad[x << 1] += v;
mx[x << 1] += v;
};
void add(int l, int r, int x, ll v) {
if (l == r) {
modify(x, v);
return ;
}
pushdown(l, r);
ll mid = l + r >> 1;
if (x <= mid) {
add(l, mid, x, v);
} else {
add(mid + 1, r, x, v);
}
pushup(l, r, mid);
}
void add(int x, ll v) {
add(1, n, x, v);
}
ll max(int l, int r, int L, int R) {
if (l >= L && r <= R) {
return mx[root(l, r)];
}
pushdown(l, r);
ll mid = l + r >> 1, res = -inf;
if (L <= mid) {
res = std::max(res, max(l, mid, L, R));
}
if (R > mid) {
res = std::max(res, max(mid + 1, r, L, R));
}
return res;
}
ll max(int l, int r) {
return max(1, n, l, r);
}
};
jiangly's
from jiangly
#include <bits/stdc++.h>
using i64 = long long;
template<class Info, class Tag>
struct LazySegmentTree {
int n;
std::vector<Info> info;
std::vector<Tag> tag;
LazySegmentTree() : n(0) {}
LazySegmentTree(int n_, Info v_ = Info()) {
init(n_, v_);
}
template<class T>
LazySegmentTree(std::vector<T> init_) {
init(init_);
}
void init(int n_, Info v_ = Info()) {
init(std::vector(n_, v_));
}
template<class T>
void init(std::vector<T> init_) {
n = init_.size();
info.assign(4 << std::__lg(n), Info());
tag.assign(4 << std::__lg(n), Tag());
std::function<void(int, int, int)> build = [&](int p, int l, int r) {
if (r - l == 1) {
info[p] = init_[l];
return;
}
int m = (l + r) / 2;
build(2 * p, l, m);
build(2 * p + 1, m, r);
pull(p);
};
build(1, 0, n);
}
void pull(int p) {
info[p] = info[2 * p] + info[2 * p + 1];
}
void apply(int p, const Tag &v) {
info[p].apply(v);
tag[p].apply(v);
}
void push(int p) {
apply(2 * p, tag[p]);
apply(2 * p + 1, tag[p]);
tag[p] = Tag();
}
void modify(int p, int l, int r, int x, const Info &v) {
if (r - l == 1) {
info[p] = v;
return;
}
int m = (l + r) / 2;
push(p);
if (x < m) {
modify(2 * p, l, m, x, v);
} else {
modify(2 * p + 1, m, r, x, v);
}
pull(p);
}
void modify(int p, const Info &v) {
modify(1, 0, n, p, v);
}
Info rangeQuery(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 m = (l + r) / 2;
push(p);
return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
}
Info rangeQuery(int l, int r) {
return rangeQuery(1, 0, n, l, r);
}
void rangeApply(int p, int l, int r, int x, int y, const Tag &v) {
if (l >= y || r <= x) {
return;
}
if (l >= x && r <= y) {
apply(p, v);
return;
}
int m = (l + r) / 2;
push(p);
rangeApply(2 * p, l, m, x, y, v);
rangeApply(2 * p + 1, m, r, x, y, v);
pull(p);
}
void rangeApply(int l, int r, const Tag &v) {
return rangeApply(1, 0, n, l, r, v);
}
template<class F>
int findFirst(int p, int l, int r, int x, int y, F pred) {
if (l >= y || r <= x || !pred(info[p])) {
return -1;
}
if (r - l == 1) {
return l;
}
int m = (l + r) / 2;
push(p);
int res = findFirst(2 * p, l, m, x, y, pred);
if (res == -1) {
res = findFirst(2 * p + 1, m, r, x, y, pred);
}
return res;
}
template<class F>
int findFirst(int l, int r, F pred) {
return findFirst(1, 0, n, l, r, pred);
}
template<class F>
int findLast(int p, int l, int r, int x, int y, F pred) {
if (l >= y || r <= x || !pred(info[p])) {
return -1;
}
if (r - l == 1) {
return l;
}
int m = (l + r) / 2;
push(p);
int res = findLast(2 * p + 1, m, r, x, y, pred);
if (res == -1) {
res = findLast(2 * p, l, m, x, y, pred);
}
return res;
}
template<class F>
int findLast(int l, int r, F pred) {
return findLast(1, 0, n, l, r, pred);
}
};
constexpr int inf = 1E9+1;
struct Min {
int x = inf;
void apply(Min t) & {
x = std::min(x, t.x);
}
};
Min operator+(Min a, Min b) {
return {std::min(a.x, b.x)};
}