[模板] 线段树
线段树
///线段树,建树O(nlogn)、修改查询O(logn),单点修改、区间查询
//需要魔改内部的,就把泛型删掉
template<class T, class F>
class SegmentTree {
const int n;
vector<T> node;
void update(int rt, int l, int r, int pos, F f) {
if (r < pos || l > pos) return;
if (l == r) {
node[rt] = f(node[rt]);
return;
}
int mid = l + r >> 1;
update(rt << 1, l, mid, pos, f);
update(rt << 1 | 1, mid + 1, r, pos, f);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
}
T query(int rt, int l, int r, int x, int y) {
if (l > y || r < x) return T::e();
if (x <= l && r <= y) return node[rt];
int mid = l + r >> 1;
return query(rt << 1, l, mid, x, y) + query(rt << 1 | 1, mid + 1, r, x, y);
}
public:
SegmentTree(int _n):n(_n), node(_n << 2, T::e()) {}
SegmentTree(int _n, const vector<T> &src):n(_n), node(_n << 2, T::e()) {
function<void(int, int, int)> build = [&](int rt, int l, int r) {
if (l == r) {
node[rt] = src[l];
return;
}
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
};
build(1, 1, n);
}
void update(int pos, F f) { update(1, 1, n, pos, f); }
T query(int x, int y) { return query(1, 1, n, x, y); }
};
///节点元封装类,定义单位元"e"、合并"+"
struct T {
int val;
static T e() { return T{ 0 }; }
friend T operator+(const T &a, const T &b) { return { a.val + b.val }; }
};
///修改元封装类,定义映射"()"
struct F {
int diff;
T operator()(const T &x) { return T{ diff + x.val }; }
};
懒标记线段树
///懒标记线段树,建树O(nlogn)、修改查询O(logn),区间修改、区间查询
//需要魔改内部的,就把泛型删掉
template<class T, class F>
class SegmentTreeLazy {
const int n;
vector<T> node;
vector<F> lazy;
void push_down(int rt) {
node[rt << 1] = lazy[rt](node[rt << 1]);
lazy[rt << 1] = lazy[rt](lazy[rt << 1]);
node[rt << 1 | 1] = lazy[rt](node[rt << 1 | 1]);
lazy[rt << 1 | 1] = lazy[rt](lazy[rt << 1 | 1]);
lazy[rt] = F::e();
}
void update(int rt, int l, int r, int x, int y, F f) {
if (l > y || r < x) return;
if (x <= l && r <= y) {
node[rt] = f(node[rt]);
lazy[rt] = f(lazy[rt]);
return;
}
push_down(rt);
int mid = l + r >> 1;
update(rt << 1, l, mid, x, y, f);
update(rt << 1 | 1, mid + 1, r, x, y, f);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
}
T query(int rt, int l, int r, int x, int y) {
if (l > y || r < x) return T::e();
if (x <= l && r <= y) return node[rt];
push_down(rt);
int mid = l + r >> 1;
return query(rt << 1, l, mid, x, y) + query(rt << 1 | 1, mid + 1, r, x, y);
}
public:
SegmentTreeLazy(int _n):n(_n), node(_n << 2, T::e()), lazy(_n << 2, F::e()) {}
SegmentTreeLazy(int _n, const vector<T> &src):n(_n), node(_n << 2, T::e()), lazy(_n << 2, F::e()) {
function<void(int, int, int)> build = [&](int rt, int l, int r) {
if (l == r) {
node[rt] = src[l];
return;
}
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
};
build(1, 1, n);
}
void update(int x, int y, F f) {
update(1, 1, n, x, y, f);
}
T query(int x, int y) {
return query(1, 1, n, x, y);
}
};
int p;
///节点元封装类,定义单位元"e"、合并"+"
struct T {
ll val;
int len;
static T e() { return T{ 0,0 }; }
friend T operator+(const T &a, const T &b) { return T{ (a.val + b.val) % p,a.len + b.len }; }
};
///修改元封装类,定义单位元"e"、映射"()"、复合"()"
struct F {
ll sum;
ll mul;
static F e() { return F{ 0,1 }; }
T operator()(T x) { return T{ (mul * x.val % p + sum * x.len % p) % p,x.len }; }
F operator()(F g) { return F{ (mul * g.sum % p + sum) % p,mul * g.mul % p }; }
};
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16929834.html