线段树
- 针对:动态区间问题。对于数组A,有如下操作:
Update(x, v):把A[x]修改为v。
Add(L, R, v):把A[L], A[L + 1], …,A[R]的值全部加v。
Set(L, R, v):把A[L], A[L + 1], …, A[R]的值全部修改为v(v >= 0)。
Quer(L, R):计算A[L], A[L + 1], …, A[R]的元素和与最值。
等等相邻区间的信息可以被合并成一个区间的操作。 - 线段树是一棵二叉树,每个结点对应一条线段[L, R], 左儿子对应线段[L, mid],右儿子对应线段[mid + 1, R](mid = (L + R) >> 1),每个结点记录该线段的信息。这里线段可代表不同含义,如数轴上真实线段,一个序列中的连续子序列,位置,权值,前缀,差分…
- 基础操作:
- 存储:(结构体,数组模拟指针)
注意: 数组开4倍大。 - 单点(上传)更新:(用子树中的结点信息更新根结点)calc
- 区间(下传)更新:(根节点的信息下传更新子树结点)pushdown
- 建树:(一般直接用单点修改代替)build
- 单点修改:(一般直接用区间修改代替)update
- 区间修改:change
- 区间查询:query
- 存储:(结构体,数组模拟指针)
struct info{
int l, r, v, tar;
}e[4 * MN];
inline void calc(int now, int l, int r)
{
if (l == r) return;
e[now].v = e[now << 1].v + e[now << 1 | 1].v;
}//以求区间和为例
inline void pushdown(int now, int l, int r)
{
if (l == r) return;
e[now << 1].v += e[now].tar * (mid - l + 1);
e[now << 1 | 1].v += e[now].tar * (r - mid);
e[now << 1].tar += e[now].tar;
e[now << 1 | 1].tar += e[now].tar;
e[now].tar = 0;
}//以给区间元素增加一个值为例
inline void build(int now, int l, int r)
{
if (l == r)
{
e[now].v = a[l];
return;
}
int mid = (l + r) >> 1;
build(now << 1, l, mid);
build(now << 1 | 1, mid + 1, r);
calc(now, l, r);
}
inline void update(int now, int l, int r, int p, int v)
{
if (l == r)
{
e[now].v += v;
return;
}
int mid = (l + r) >> 1;
if (p <= mid) update(now << 1, l, mid, p, v);
else update(now << 1 | 1, mid + 1, r, p, v);
calc(now, l, r);
}//以给a[p]增加v为例
inline void change(int now, int l, int r, int x, int y, int v)
{
pushdown(now, l, r);
if (x <= l && r <= y)
{
e[now].v += v * (r - l + 1);
e[now].tar += v;
return;
}
int mid = (l + r) >> 1;
if (x <= mid) change(now << 1, l, mid, x, y, v);
if (y > mid) change(now << 1 | 1, mid + 1, r, x, y, v);
calc(now, l, c);
}//以给区间[x, y]元素增加v为例
inline int query(int now, int l, int r, int x, int y)
{
if (x <= l && r <= y) return e[now].v;
pushdown(now, l, r);
int mid = (l + r) >> 1, ans;
if (x <= mid) ans = query(now << 1, l, mid, x, y);
if (y > mid) ans += query(now << 1 | 1, mid + 1, r, x, y);
return ans;
}//以求区间[x, y]元素和为例
- 每个操作时间复杂度O(log n)
其他操作模版网上很多。