10pts求调

P3372 【模板】线段树 1

aVSCode @ 2025-01-01 14:06:19

#include<iostream>
#include<cmath>
using namespace std;
#define int long long
long long a[100005],t[400005],tag[400005];
void build(int l,int r,int now){
    if(l==r) t[now]=a[l];
    else{
        int mid=(l+r)>>1;
        build(l,mid,now*2);
        build(mid+1,r,now*2+1);
        t[now]=t[now*2]+t[now*2+1];
    }
}
void push_down(int l,int r,int now){
    int mid=(l+r)>>1;
    t[now*2]+=(mid-l+1)*tag[now];
    tag[now*2]=tag[now];
    t[now*2+1]+=(r-mid)*tag[now];
    tag[now*2+1]=tag[now];
}
long long find(int l,int r,int o,int p,int now){
    if(l<=o&&r>=p) return t[now];//[o,p]e[l,r]
    else{
        if(tag[now]!=0){
            push_down(o,p,now);//tag下放
            tag[now]=0;
        }
        int mid=(o+p)>>1;
        long long res=0;
        if(mid>=l) res+=find(l,r,o,mid,now*2);
        if(mid<r) res+=find(l,r,mid+1,p,now*2+1);
        return res;
    }
}
void add(int l,int r,int o,int p,long long num,int now){
    // cout<<o<<" "<<p<<" "<<now<<" "<<tag[now]<<endl;
    if(l<=o&&p<=r){
        // cout<<"Executed"<<endl;
        t[now]+=(p-o+1)*num;
        tag[now]=num;
        // cout<<o<<" "<<p<<" "<<now<<" "<<t[now]<<endl;
    }
    else{
        if(tag[now]!=0){
            push_down(o,p,now);
            tag[now]=0;
        }
        int mid=(o+p)>>1;
        if(mid>=l) add(l,r,o,mid,num,now*2);
        if(mid<r) add(l,r,mid+1,p,num,now*2+1);
        t[now]=t[now*2]+t[now*2+1];
    }
    // cout<<o<<" "<<p<<" "<<now<<" "<<tag[now]<<endl;
}
int n,m,op;
long long x,y,k;
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,n,1);
    for(int i=1;i<=m;i++){
        cin>>op;
        if(op==1){
            cin>>x>>y>>k;
            add(x,y,1,n,k,1);
        }
        if(op==2){
            cin>>x>>y;
            cout<<find(x,y,1,n,1)<<endl;
        }
    }
    return 0;
}

by XVETV6 @ 2025-01-01 14:24:31

tag[now]= ... -> tag[now] += ...

by guanzisheng2 @ 2025-01-01 14:24:35

@aVSCode

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a[500005],x,y,z,k;
struct node{
    int l,r,s,lazytag;
}tree[2000005];
void pushup(int x){
    tree[x].s=tree[x*2].s+tree[x*2+1].s;
}
void pushdown(int x){
    int t=tree[x].lazytag;
    tree[2*x].s+=(tree[2*x].r-tree[2*x].l+1)*t;
    tree[2*x].lazytag+=t;
    tree[2*x+1].s+=(tree[2*x+1].r-tree[2*x+1].l+1)*t;
    tree[2*x+1].lazytag+=t;
    tree[x].lazytag=0;
}
void build(int l,int r,int z){
    tree[z].l=l,tree[z].r=r,tree[z].lazytag=0;
    if(l==r){
        tree[z].s=a[l];
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,z*2);
    build(mid+1,r,z*2+1);
    pushup(z);
}
void add(int x,int y,int z,int k){
    if(tree[z].l>=x&&tree[z].r<=y){
        tree[z].s+=k*(tree[z].r-tree[z].l+1),tree[z].lazytag+=k;
        return ;
    }
    pushdown(z);
    int mid=(tree[z].l+tree[z].r)/2;
    if(x<=mid) add(x,y,z*2,k);
    if(y>mid) add(x,y,z*2+1,k);
    pushup(z);
}
int qry(int x,int y,int z){
    if(x<=tree[z].l&&tree[z].r<=y) return tree[z].s;
    int mid=(tree[z].l+tree[z].r)/2,ans=0;
    pushdown(z);
    if(mid>=x) ans+=qry(x,y,z*2);
    if(y>mid) ans+=qry(x,y,z*2+1);
    return ans;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,n,1);
    while(m--){
        cin>>z>>x>>y;
        if(z==1) cin>>k,add(x,y,1,k);
        else cout<<qry(x,y,1)<<"\n";
    }
    return 0;
}

|