10分求调

P3372 【模板】线段树 1

RainBow_doge @ 2024-07-15 20:49:47

样例过了,但只有10分

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e5+10;
int n,m;
int w[N],lz[N],a[N];
void build(int id,int l,int r ){
    if(l==r){
    w[id]=a[l];
    return; 
    }
    int mid=l+r>>1;
    build(id<<1,l,mid);
    build(id<<1|1,mid+1,r);
    w[id]=w[id<<1]+w[id<<1|1];
}

void push_down(int id,int l,int r,int mid){
    if(lz[id]!=0){
        w[id<<1]+=(mid-l+1)*lz[id];
        w[id<<1|1]+=(r-mid+1+1)*lz[id];
        lz[id<<1]+=lz[id];
        lz[id<<1|1]+=lz[id];
        lz[id]=0;
    }
}
void update(int id,int l,int r,int L,int R,int k){
    if(L<=l&&R>=r){
        w[id]+=(r-l+1)*k;
        lz[id]+=k;
        return;
    }
    int mid=l+r>>1;
    push_down(id,l,r,mid);
    if(L<=mid) update(id<<1,l,mid,L,R,k);
    if(R>mid) update(id<<1|1,mid+1,r,L,R,k);
    w[id]=w[id<<1]+w[id<<1|1];
}

int find(int id,int l,int r,int L,int R){
    int res=0;
    if(L<=l&&r<=R) return w[id];
    int mid=l+r>>1;
    push_down(id,l,r,mid);
    if(L<=mid) res+=find(id<<1,l,mid,L,R);
    if(R>mid) res+=find(id<<1|1,mid+1,r,L,R);
//  w[id]=w[id<<1]+w[id<<1|1];
    return res;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    while(m--){
        int x,y,op,k;
        cin>>op;
        if(op==2){
            cin>>x>>y;
        cout<<find(1,1,n,x,y)<<endl;
        }
        else{
            cin>>x>>y>>k;
            update(1,1,n,x,y,k);
        }
    }
}

by jy20091121 @ 2024-07-15 20:52:10

你这个mid干什么用的


by jy20091121 @ 2024-07-15 20:52:48

void push_down(int id,int l,int r,int mid){
    if(lz[id]!=0){
        w[id<<1]+=(mid-l+1)*lz[id];
        w[id<<1|1]+=(r-mid+1+1)*lz[id];
        lz[id<<1]+=lz[id];
        lz[id<<1|1]+=lz[id];
        lz[id]=0;
    }
}

你直接用r-l+1就行


by zhongpeilin @ 2024-07-15 20:53:33

@RainBow_doge void push_down(int id,int l,int r,int mid){ if(lz[id]!=0){ w[id<<1]+=(mid-l+1)lz[id]; w[id<<1|1]+=(r-(mid+1)+1)lz[id]; lz[id<<1]+=lz[id]; lz[id<<1|1]+=lz[id]; lz[id]=0; } }


by zbrprogrammer @ 2024-07-15 20:53:44

line 12: int mid=l+r>>1; -> int mid=(l+r)>>1;

line 23: w[id<<1|1]+=(r-mid+1+1)*lz[id]; -> w[id<<1|1]+=(r-mid)*lz[id];

line 35/45: 同line 12


by zhongpeilin @ 2024-07-15 20:54:06


void push_down(int id,int l,int r,int mid){
    if(lz[id]!=0){
        w[id<<1]+=(mid-l+1)*lz[id];
        w[id<<1|1]+=(r-(mid+1)+1)*lz[id];
        lz[id<<1]+=lz[id];
        lz[id<<1|1]+=lz[id];
        lz[id]=0;
    }
}

by zbrprogrammer @ 2024-07-15 20:55:43

@zhangjiayii 左右儿子pushdown不能用r-l+1代替


by jy20091121 @ 2024-07-15 21:01:19

@zbrprogrammer 求和用r-l+1 左右儿子id*2 id*2+1


by guorunduo @ 2024-07-15 21:05:56

hp


by RainBow_doge @ 2024-07-15 21:07:36

谢谢大家 AC了


by zbrprogrammer @ 2024-07-15 21:19:09

@zhangjiayii pushdown是修改左右儿子的w值,不是求和,需要mid做界定


| 下一页