带有lazy标记的线段树

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,val,com,s[100000];
struct st{
    int l,r,val,add;
}tr[10000000];
void build(int l,int r,int k)
{
    tr[k].l=l;
    tr[k].r=r;
    if(l==r)
    {
        tr[k].val=s[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,k<<1);
    build(mid+1,r,k<<1|1);
    tr[k].val = tr[k<<1].val + tr[k<<1|1].val;    
}
void pus(int k)
{
    int l=tr[k].l;
    int r=tr[k].r;
    tr[k].add+=tr[k>>1].add;
    tr[k].val+=(r-l+1)*tr[k>>1].add;
}
void update(int x,int y,int k,int val)
{
    if(tr[k].add)
    {
        pus(k<<1);
        pus(k<<1|1);
        tr[k].add=0;
    }
    int l=tr[k].l;
    int r=tr[k].r;
    int mid=(l+r)>>1;
    if(y<l || x>r)
        return;
    if(x<=l && r<=y)
    {
        tr[k].val += (l-r+1)*val;
        tr[k].add += val;
        return;
    }
    else 
    {
        if(x<=mid)
            update(x,y,k<<1,val);
        if(y>mid)
            update(x,y,k<<1|1,val);
        tr[k].val = tr[k<<1].val + tr[k<<1|1].val;
    }    
}
int sum(int x,int y,int k)
{
    if(tr[k].add)
    {
        pus(k<<1);
        pus(k<<1|1);
        tr[k].add=0;
    }
    int l=tr[k].l;
    int r=tr[k].r;
    int mid=(l+r)>>1;
    if(y<l || x>r)
        return 0;
    if(x<=l && r<=y)
        return tr[k].val;
    else
    {
        int ans=0;
        if(x<=mid)
            ans+=sum(x,y,k<<1);
        if(y>mid)
            ans+=sum(x,y,k<<1|1);
        return ans;
    }
}
main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&s[i]);
    build(1,n,1);
    while(m--)
    {
        scanf("%d",&com);
        if(com==1)
        {
            scanf("%d%d%d",&x,&y,&val);
            update(x,y,1,val);
        }
        else
        {
            scanf("%d%d",&x,&y);
            printf("%d
",sum(x,y,1));
        }
    }
}
原文地址:https://www.cnblogs.com/kczno1fans/p/7353473.html