Loading

线段树

为防止老年痴呆,特地贴一份线段树的板子在此

尝有老登云"老年痴呆者,亦可传此线段树之模板咦!"自觉废物,故贴此详解,以防老年痴呆(悲)

完整代码

线段树↓

struct node{
    int l,r;
    long long sum,lazy;
}t[114514];

更新线段树(将左右子节点的值传递到该节点)

void update(int i){
    t[i].sum = t[i<<1].sum + t[i<<1|1].sum;
}

lazy_tag传递下去

void pushdown(i)
{
    if(t[i].lazy == 0)
        return;
    t[i<<1].lazy += t[i].lazy;
    t[i<<1|1].lazy += t[i].lazy;
    t[i<<1].sum += (t[i<<1].r - t[i<<1].l+1) * t[i].lazy;//一个区间数字数量×lazy_tag标记所增加的数=所需增加的数
    t[i<<1|1].sum += (t[i<<1|1].r - t[i<<1|1].l+1) * t[i].lazy;//右区间同理
    t[i].lazy = 0;//清理
}

如题,建树

void buildtree(int i,int l,int r)//传递区间范围,编号
{
    t[i].l = l;
    t[i].r = r;
    if(l==r)
    {
        t[i].sum = a[l];
        return;
    }

    int mid = (l+r)>>1;
    buildtree(i<<1,l,mid);
    buildtree(i<<1|1,mid+1,r);
    update(i);//跟新,将i号节点的左右子节点传递上来
}

区间修改

void change(int i,int l,int r,int x)
{
    if(l<=t[i].l && t[i].r <= r)
    {
        t[i].sum += (t[i].r-t[i].l+1) * x;
        t[i].lazy += x;
        return;
    }
    if(t[i].l > r || t[i].r < l)
        return ;
    pushdown(i); //保证其子节点不会过期,保证后chagne的正确性
    change(i<<1,l,r,x);
    change(i<<1|1,l,r,x);
    update(i);//更新
}

区间查询

int query(int i,int l,int r)
{
    if(l<=t[i].l && t[i].r <= r)//当前区间完全被查询区间所包含
        return t[i].sum;//直接返回
    if(t[i].l > r || t[i].r < l) //完全没有交集的区间
        return 0;//返回0
    pushdown(i);//更新数据,保证正确性,防止过期
    return query(i<<1,l,r) + query(i<<1|1,l,r);  //返回左右子区间的和
}
posted @ 2025-07-17 11:14  Venlacy  阅读(30)  评论(0)    收藏  举报