P3372【模板】线段树1

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+100;
typedef long long ll;
struct node {
    int l,r;
    ll sum;
    ll lazy;
}segTree[maxn*4];
ll a[maxn];
int n,m;
void build (int i,int l,int r) {
    segTree[i].l=l;
    segTree[i].r=r;
    if (l==r) {
        segTree[i].sum=a[l];
        return;
    }
    int mid=(segTree[i].l+segTree[i].r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum;
} 
void spread (int i) {
    if (segTree[i].lazy) {
        segTree[i<<1].sum+=(segTree[i<<1].r-segTree[i<<1].l+1)*segTree[i].lazy;
        segTree[i<<1].lazy+=segTree[i].lazy;
        segTree[i<<1|1].sum+=(segTree[i<<1|1].r-segTree[i<<1|1].l+1)*segTree[i].lazy;
        segTree[i<<1|1].lazy+=segTree[i].lazy;
        segTree[i].lazy=0; 
    }
} 
void add (int i,int l,int r,ll x) {
    if (segTree[i].l>=l&&segTree[i].r<=r) {
        segTree[i].sum+=(segTree[i].r-segTree[i].l+1)*x;
        segTree[i].lazy+=x;
        return;
    }
    spread(i);
    int mid=(segTree[i].l+segTree[i].r)>>1;
    if (l<=mid)
        add(i<<1,l,r,x);
    if (r>mid)
        add(i<<1|1,l,r,x);
    segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum;
} 
ll query (int i,int l,int r) {
    if (segTree[i].l>=l&&segTree[i].r<=r) {
        return segTree[i].sum;
    }
    spread(i);
    int mid=(segTree[i].l+segTree[i].r)>>1;
    ll ans=0;
    if (l<=mid)
        ans+=query(i<<1,l,r);
    if (r>mid)
        ans+=query(i<<1|1,l,r);
    return ans;
}
int main () {
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) scanf("%lld",a+i);
    build(1,1,n);
    for (int i=1;i<=m;i++) {
        int op;
        scanf("%d",&op);
        if (op==1) {
            int x,y;
            ll k;
            scanf("%d%d%lld",&x,&y,&k);
            add(1,x,y,k);
        }
        else {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%lld
",query(1,x,y));
        }
    }
}
原文地址:https://www.cnblogs.com/zhanglichen/p/13448520.html