zkw线段树学习笔记

强行学习zkw线段树qwq

参考资料:zkw 统计的力量
某位神犇的博客

一、建树:

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];
    }
}

猜你喜欢

转载自www.cnblogs.com/pushinl/p/9850257.html