线段树 (区间修改 区间查询)

https://www.luogu.com.cn/problem/P3372

#include<bits/stdc++.h> 
#define N 500005
#define endl '
' 
#define _for(i,a,b) for(int i=a;i<b;i++)
using namespace std;
typedef long long ll; 
ll a[N];
struct Node{
    int l,r; ll sum,lazy;
}T[N*4];
void Build(int v,int l,int r){
    T[v].l=l,T[v].r=r;
    if( l==r ){
        T[v].sum=a[r];
        return ;
    }
    int mid=(r+l)/2;
    Build( v*2,l,mid );
    Build( v*2+1,mid+1,r );
    T[v].sum= T[v*2].sum + T[v*2+1].sum;
}
void push_down(int i)
{
    if(T[i].lazy!=0)
    {
        T[i*2].lazy+=T[i].lazy;//×óÓÒ¶ù×Ó·Ö±ð¼ÓÉϸ¸Ç×µÄlz
        T[i*2+1].lazy+=T[i].lazy;
        int mid=(T[i].l+T[i].r)/2;
        T[i*2].sum+=T[i].lazy*(T[i*2].r-T[i*2].l+1);//×óÓÒ·Ö±ðÇóºÍ¼ÓÆðÀ´
        T[i*2+1].sum+=T[i].lazy*(T[i*2+1].r-T[i*2+1].l+1);
        T[i].lazy=0;//¸¸Ç×lz¹éÁã
    }
    return ;
}
void Add(int v,int l,int r,int k){
    if( T[v].l>=l && T[v].r<=r ){
        T[v].sum+= ( (T[v].r-T[v].l+1)*k ) ;
        T[v].lazy+=k;
        return ;
    }
    if( T[v].l>r || T[v].r<l ) return ;
    push_down(v);
    if( T[v*2].r>=l ) Add( v*2,l,r,k );
    if( T[v*2+1].l<=r ) Add( v*2+1,l,r,k ); 
    T[v].sum= T[v*2].sum+T[v*2+1].sum;
}
ll Search(int v,int l,int r){
    if( T[v].l>=l && T[v].r<=r ){
        return T[v].sum ;
    }
    if( T[v].l>r || T[v].r<l ) return 0;
    push_down(v);
    ll res=0;
    if( T[v*2].r>=l ) res+=Search(v*2,l,r);
    if( T[v*2+1].l<=r ) res+=Search( v*2+1,l,r ); 
    return res;
}
int main(){    
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 
    int n,m;   cin>>n>>m;
    _for(i,1,n+1) cin>>a[i];
    Build(1,1,n);
    while(m--){
        int x,y,k,ch;
        cin>>ch>>x>>y;
        if( ch==1 ){
            cin>>k;
            Add(1,x,y,k);
        }
        else{
            cout<<Search(1,x,y)<<endl;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/SunChuangYu/p/12343888.html