10分求调

P3372 【模板】线段树 1

lutaoquan2012 @ 2023-12-12 19:49:10

//
// Created by 55062 on 2023/12/12.
//
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,opt,xx,y,kk,aa[100010];
struct node{
    ll sum,delta,l,r;
}a[20000010];
void pushup(ll x){
    a[x].sum=a[x*2].sum+a[x*2+1].sum;
}
void build(ll l,ll r,ll x){
    a[x].delta=0;
    a[x].l=l;
    a[x].r=r;
    if(l==r){
        a[x].sum=aa[l];
        return ;
    }
    ll mid=(l+r)/2;
    build(l,mid,x*2);
    build(mid+1,r,x*2+1);
    pushup(x);
}
void pushdown(ll x,ll l,ll r){
    ll mid=(l+r)/2;
    a[x*2].delta+=a[x].delta;
    a[x*2+1].delta+=a[x].delta;
    a[x*2].sum+=a[x].delta*(mid-l+1);
    a[x*2+1].sum+=a[x].delta*(r-mid+2);
    a[x].delta=0;
}void Tag(ll L,ll R,ll l,ll r,ll x,ll k){
    if(L<=l&&r<=R){
        a[x].sum+=k*(r-l+1);
        a[x].delta+=k;
        return ;
    }pushdown(x,l,r);
    ll mid=(l+r)/2;
    if(L<=mid) Tag(L,R,l,mid,x*2,k);
    if(R>mid) Tag(L,R,mid+1,r,x*2+1,k);
    pushup(x);
}ll query(ll L,ll R,ll l,ll r,ll x){
    ll ans=0;
    if(L<=l&&r<=R) return a[x].sum;
    ll mid=(l+r)/2;
    pushdown(x,l,r);
    if(L<=mid) ans+= query(L,R,l,mid,x*2);
    if(R>mid) ans+= query(L,R,mid+1,r,x*2+1);
    return ans;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>aa[i];
    build(1,n,1);
    for(int i=1;i<=m;i++){
        cin>>opt>>xx>>y;
        if(opt==1){
            cin>>kk;
            Tag(xx,y,1,n,1,kk);
        }else cout<<query(xx,y,1,n,1)<<endl;
    }
    return 0;
}

by DGH_Didi @ 2023-12-12 19:51:25

void pushdown(ll x,ll l,ll r){
    ll mid=(l+r)/2;
    a[x*2].delta+=a[x].delta;
    a[x*2+1].delta+=a[x].delta;
    a[x*2].sum+=a[x].delta*(mid-l+1);
    a[x*2+1].sum+=a[x].delta*(r-mid); // mid + 1 ~ r 共有 (r - mid) 个数
    a[x].delta=0;
}

by lutaoquan2012 @ 2023-12-12 19:54:34

谢谢大佬,明白了,当时纯属脑残


|