线段树0分求调

P3372 【模板】线段树 1

space_P @ 2024-11-22 20:08:11

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=101111;
int n,m,a[N];
int tr[N<<2],add[N<<2];
int ls(int k){
    return k<<1;
}
int rs(int k){
    return (k<<1)|1;
}
void pu(int k){
    tr[k]=tr[ls(k)]+tr[rs(k)];
}
void pd(int k,int l,int r){
    add[ls(k)]+=add[k];
    add[rs(k)]+=add[k];
    int mid=(l+r)>>1;
    tr[ls(k)]+=add[k]*(mid-l+1);
    tr[rs(k)]+=add[k]*(r-mid);
    add[k]=0;
}
void blind(int k,int l,int r){
    if(l==r){
        tr[k]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    blind(ls(k),l,mid);
    blind(rs(k),mid+1,r);
    pu(k);
}
void ru(int k,int l,int r,int ul,int ur,int ad){
    if(ul > r || ur < l) return;
    if(ul >= l && ur <= r){
        add[k]+=ad;
        tr[k]+=ad*(r-l+1);
        return;
    }
    pd(k,l,r);
    int mid=(l+r)>>1;
    ru(ls(k),l,mid,ul,ur,ad);
    ru(rs(k),mid,r,ul,ur,ad);
    pu(k);
}
int rq(int k,int l,int r,int ql,int qr){
    if(qr < l || ql >r) return 0;
    if(qr >= l && qr <= r){
        return tr[k];
    }
    int mid=(l+r)>>1;
    pd(k,l,r);
    return rq(ls(k),l,mid,ql,qr)+rq(rs(k),mid+1,r,ql,qr);
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    blind(1,1,n);
    while(m--){
        int opt;
        cin>>opt;
        if(opt^1){
            int l,r;
            cin>>l>>r;
            cout<<rq(1,1,n,l,r)<<endl;
        }
        else {
            int l,r,ad;
            cin>>l>>r>>ad;
            ru(1,1,n,l,r,ad);
        }
    }
    return 0;
}

by lct201714 @ 2024-11-22 20:12:30

应该是

if(ul<=l&&r<=ur){
  …
  return ;
}

if(ql<=l&&r<=qr){
  …
  return ;
}

by INTP_A @ 2024-11-22 20:25:14

ru(ls(k),l,mid,ul,ur,ad);
    ru(rs(k),mid,r,ul,ur,ad);

这里下面的ru应该是mid+1 @space_P


by space_P @ 2024-11-22 21:44:06

已经AC了,谢谢dalao


|