♂蒟♂蒻♂线♂段♂树♂性♂感♂代♂码♂在♂线♂求♂调♂教♂

P3372 【模板】线段树 1

alex_liu @ 2023-03-07 14:07:48

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,lazy[100005],ans[100005<<2],a[100005<<2];
inline void build(int x,int y,int num){
    if(x^y)build(x,x+y>>1,num<<1),build((x+y>>1)+1,y,num<<1|1),ans[num]=ans[num<<1]+ans[num<<1|1];
    else ans[num]=a[x];
}
inline void update(int lx,int ly,int x,int y,int num,int k){
    if(lx<=x&&ly>=y){
        lazy[num]+=k,ans[num]+=(y-x+1)*k;
        return;
    }
    int mid=x+y>>1;
    lazy[num<<1]+=lazy[num],lazy[num<<1|1]+=lazy[num];
    ans[num<<1]+=lazy[num]*(mid-x+1),ans[num<<1|1]+=lazy[num]*(y-mid);
    lazy[num]=0;
    if(lx<=mid)update(lx,ly,x,mid,num<<1,k);
    if(ly>mid)update(lx,ly,mid+1,y,num<<1|1,k);
    ans[num]=ans[num<<1]+ans[num<<1|1];
}
inline int query(int lx,int ly,int x,int y,int num){
    if(lx<=x&&ly>=y)return ans[num];
    int res=0,mid=x+y>>1;
    lazy[num<<1]+=lazy[num],lazy[num<<1|1]+=lazy[num];
    ans[num<<1]+=lazy[num]*(mid-x+1),ans[num<<1|1]+=lazy[num]*(y-mid);
    lazy[num]=0;
    if(lx<=mid)res+=query(lx,ly,x,mid,num<<1);
    if(ly>mid)res+=query(lx,ly,mid+1,y,num<<1|1);
    return res;
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    build(1,n,1);
    for(int i=1,opt,x,y,k;i<=m;i++){
        cin>>opt>>x>>y;
        if(opt==1)cin>>k,update(x,y,1,n,1,k);
        else cout<<query(x,y,1,n,1)<<endl;
    }
    return 0;
}

by y_kx_b @ 2023-03-07 14:16:43

btdjbl(doge


by y_kx_b @ 2023-03-07 14:20:31

@alex_liu 你 lazy 不开 4 倍空间?

其实 lazy 好像 2倍空间就够了,不过我不清楚,我一直写的是 2 倍空间的线段树(


by 快速herself变换 @ 2023-03-07 14:32:14

lazy数组开4倍空间 qwq


by Z1qqurat @ 2023-03-07 15:13:32

这♂个♂标♂题♂党♂好♂评♂


by zjx331 @ 2023-03-07 16:39:14

哲♂学♂标♂题♂好♂评


by alex_liu @ 2023-03-08 13:10:43

@y_kx_b /bx


|