线段树(模板)

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N=1e5+10;

int w[N];
int n,m;
struct SegTree
{
    int l,r;
    int sum,add;
}tr[N<<2];

void pushdown(int u)
{
    SegTree& root =tr[u], &left=tr[u<<1],&right=tr[u<<1|1];
    if(root.add)
    {
        left.add+=root.add,left.sum+=(left.r-left.l+1)*root.add;
        right.add+=root.add,right.sum+=(right.r-right.l+1)*root.add;
        root.add=0;
    }
}

void pushup(int u)
{
    tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}

void build(int u,int l,int r)
{
    if(l==r)tr[u]={l,r,w[r],0};
    else
    {
        tr[u]={l,r};
        int mid=(l+r)>>1;
        build(u<<1,l,mid),build(u<<1|1,mid+1,r);
        pushup(u);
    }
}

void modify(int u,int l,int r,int x)
{
    if(tr[u].l>=l&&tr[u].r<=r)
    {
        tr[u].sum+=(tr[u].r-tr[u].l+1)*x;
        tr[u].add+=x;
    }
    else
    {
        pushdown(u);
        int mid=(tr[u].l+tr[u].r)>>1;
        if(l<=mid)modify(u<<1,l,r,x);
        if(r>mid)modify(u<<1|1,l,r,x);
        pushup(u);
    }
}

int query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r)return tr[u].sum;
    pushdown(u);
    int mid=(tr[u].l+tr[u].r)>>1;
    int sum=0;
    if(l<=mid)sum=query(u<<1,l,r);
    if(r>mid)sum+=query(u<<1|1,l,r);
    return sum;
}

signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>w[i];
    build(1,1,n);
    while(m--)
    {
        int l,r,x,op;
        cin>>op;
        if(op==1)
        {
            cin>>l>>r>>x;
            modify(1,l,r,x);
        }
        else
        {
            cin>>l>>r;
            cout<<query(1,l,r)<<endl;
        }
    }
    return 0;
}
posted @ 2025-04-18 15:30  ha000star  阅读(11)  评论(0)    收藏  举报