全WA求调

P3372 【模板】线段树 1

mincrafter_or_cy @ 2024-07-22 21:01:43

#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
long long n;
long long a[maxn],sum[maxn<<2]/*和*/,b[maxn<<2]/*标记*/;
void build(long long l,long long r,long long p){//堆式建树
    if(l==r){sum[p]=a[l];return;} //将节点赋值
    long long m=l+((r-l)>>1);
    build(l,m,p<<1);
    build(m+1,r,(p<<1)|1l);  //分别建立子树
    sum[p]=sum[p<<1]+sum[(p<<1)|1l];
}
void pushdown(long long p,long long s,long long t){
    if(b[p]==0) return;
    long long m=s+((s-t)>>1);
    sum[p<<1]+=b[p]*(m-s+1l);
    sum[(p<<1)|1]+=b[p]*(t-m);
    b[p<<1]+=b[p];
    b[(p<<1)|1l]+=b[p];
    b[p]=0;
}
void update(long long l,long long r,long long c,long long s,long long t,long long p){
    if(l<=s&&t<=r){sum[p]+=(t-s+1l)*c;b[p]+=c;return;} //区间被包含
    long long m=s+((t-s)>>1);
    pushdown(p,s,t);
    if(l<=m) update(l,r,c,s,m,p<<1);//本行和下面的一行用来更新p*2和p*2+1的节点
    if(r>m) update(l,r,c,m+1,t,(p<<1)|1l);
    sum[p]=sum[p<<1]+sum[(p<<1)|1l];  //计算该节点区间
}
long long getsum(long long l,long long r,long long s,long long t,long long p) {
    if(l<=s&&t<=r) return sum[p];
    long long m=s+((t-s)>>1);
    pushdown(p,s,t);
    long long ans=0;
    if(l<=m) ans=getsum(l,r,s,m,p<<1);//本行和下面的一行用来获取p*2和p*2+1的答案
    if(r>m) ans+=getsum(l,r,m+1,t,(p<<1)|1l);
    return ans;
}
int main(){
    long long q,type,x,y,k;
    scanf("%lld%lld",&n,&q);
    for(long long i=1l;i<=n;i++)
        scanf("%lld",&a[i]);
    build(1l,n,1l);
    for(;q;q--){
        scanf("%lld%lld%lld",&type,&x,&y);
        if(type==2) printf("%lld\n",getsum(x,y,1l,n,1l));
        else{scanf("%lld",&k);update(x,y,k,1l,n,1l);}
    }
    return 0;
}

by W_Galaxy @ 2024-07-22 21:24:46

第15行是

long long m=s+((t-s)>>1);

|