强行学习zkw线段树qwq
一、建树:
zkw线段树使用堆式存储qwq
首先你要写个循环,让\(m\)(非叶节点数)大于\(n\)(叶结点数),以此保证这棵树的叶子能够容纳你要维护的\(n\)个值
然后你要从\(m\)倒推到 \(1\) 号节点(注意是\(M\)倒推回\(1\) ,保证维护每个节点时该节点的孩子都已经被维护完毕),让每个节点维护它左右孩子的信息。
下面这段代码里维护的是最大值、最小值、前缀和。
inline void build(int n){
for(m=1;m<n;m<<=1);//开大空间
for(int i=m+1;i<=m+n;i++) a[i]=read();//原始数组
for(int i=m-1;i;--i){
sum[i]=a[i<<1]+a[i<<1|1],
mn[i]=min(mn[i<<1],mn[i<<1|1]),
mx[i]=max(mx[i<<1],mx[i<<1|1]);
}
}
但这样写不支持修改qwq所以这样写
inline void build(){
for(m=1;m<=n;m<<=1);
for(int i=m+1;i<=m+n;++i)
sum[i]=mn[i]=mx[i]=read();
for(int i=m-1;i;--i){
sum[i]=sum[i<<1]+sum[i<<1|1];
mn[i]=min(mn[i<<1],mn[i<<1|1]),
mn[i<<1]-=mn[i],mn[i<<1|1]-=mn[i];
mx[i]=max(mx[i<<1],mx[i<<1|1]),
mx[i<<1]-=mx[i],mx[i<<1|1]-=mx[i];
}
}