1.建树与维护
由于二叉树的自身特性,对于每个父亲节点的编号i,他的两个儿子的编号分别是2i和2i+1,所以我们考虑写两个O(1)的取儿子函数:
struct Node {
int l, r;
long long v,add; //区间的最大值
}tr[N * 4];
//v代表该节点维护的值,l,r代表该节点维护的区间范围 至于add涉及到一个叫懒标记的东西
//此处的inlineinline可以有效防止无需入栈的信息入栈,节省时间和空间。
inline int ls(int p){return p<<1;}//左儿子
inline int rs(int p){return p<<1|1;}//右儿子
//回溯,拿子结点的信息更新父节点, 即pushup操作(build-建树操作 modify-修改操作 中会用到)
void push_up_min(int p){//max min sum
tr[u].v = min(tr[u << 1].v, tr[u << 1 | 1].v);
//tr[u].v = max(tr[u << 1].v, tr[u << 1 | 1].v); 更新父节点最大值
//tr[u].v = tr[u << 1].v + tr[u << 1 | 1].v; 更新父节点总和
}