0分求调

P3372 【模板】线段树 1

chenyixuan180 @ 2024-10-09 13:11:02

错哪了,

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll tree[400005];
ll val[400005];
void build(int p,int L,int R){
    if(L==R){
        scanf("%lld",&tree[p]);
        return;
    }
    int mid=(L+R)>>1;
    build(p*2,L,mid);
    build(p*2+1,mid+1,R);
    tree[p]=tree[p*2]+tree[p*2+1];
    return ;
}
void update(int l,int r,int p,ll c,int L,int R){
    if(l>=L&&r<=R){
        tree[p]+=(l-r+1)*c,val[p]+=c;
        return ;
    }
    int mid=(l+r)>>1;
    if(val[p]&&l!=r){
        tree[p*2]+=val[p]*(mid-l+1);
        tree[p*2+1]+=val[p]*(r-mid);
        val[p*2]+=val[p],val[p*2+1]+=val[p];
        val[p]=0; 
    }
    if(L<=mid)update(l,mid,p*2,c,L,R);
    if(R>mid)update(mid+1,r,p*2+1,c,L,R);
    tree[p]=tree[p*2]+tree[p*2+1];
    return;
}
ll ask(int l,int r,int p,int L,int R){
    if(L<=l&&R>=r)return tree[p];
    int mid=(l+r)>>1;
    if(val[p]){
        tree[p*2]+=val[p]*(mid-l+1);
        tree[p*2+1]+=val[p]*(r-mid);
        val[p*2]+=val[p],val[p*2+1]+=val[p];
        val[p]=0;
    }
    ll sum=0;
    if(L<=mid)sum+=ask(l,mid,p*2,L,R);
    if(R>mid)sum+=ask(mid+1,r,p*2+1,L,R);
    return sum;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while(m--){
        ll x,y,k;
        scanf("%lld",&k);
        if(k==2){
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",ask(1,n,1,x,y));
        }
        if(k==1){
            scanf("%lld%lld%lld",&x,&y,&k);
            update(1,n,1,k,x,y);
        }
    }
    return 0;
}

by wintorsd @ 2024-10-09 13:17:22

???


by wintorsd @ 2024-10-09 14:01:15

就多练 @chenyixuan180 (l-r+1)


by chenyixuan180 @ 2024-10-09 14:01:53

@wintorsd 知道了


by wintorsd @ 2024-10-09 14:02:31

线段树要多练的


|