分块全WA求助

P3372 【模板】线段树 1

MoGuYun_12 @ 2024-03-31 20:37:03

#include <bits/stdc++.h>

using namespace std;
#define N 100001
#define block(i) ((i-1)/sqr+1)
typedef long long ll;
int n,m,sqr;
ll a[N],st[N],ed[N],sum[N],add_tag[N];

void init(){
    sqr=sqrt(n);
    for(int i=1;i<=n;i++) st[block(i)]=0x7fffffff;
    for(ll i=1;i<=n;i++){
        st[block(i)]=min(st[block(i)],i);
        ed[block(i)]=max(ed[block(i)],i);
        sum[block(i)]+=a[i];
    }
}
void add(int l,int r,int k){
    int bl=block(l),br=block(r);
    if(bl==br){
        for(int i=l;i<=r;i++) a[i]+=k,sum[bl]+=k;
        return;
    }
    for(int i=bl+1;i<br;i++) add_tag[i]+=k,sum[i]+=sqr*k;
    for(int i=l;i<=ed[bl];i++) a[i]+=k,sum[bl]+=k;
    for(int i=st[br];i<=r;i++) a[i]+=k,sum[br]+=k;
}
ll query(int l,int r){
    ll bl=block(l),br=block(r),ans=0;
    if(bl==br){
        for(int i=l;i<=r;i++) ans=ans+a[i]+add_tag[bl];
        return ans;
    }
    for(int i=bl+1;i<br;i++) ans+=sum[i];
    for(int i=l;i<=ed[bl];i++) ans=ans+a[i]+add_tag[bl];
    for(int i=st[br];i<=r;i++) ans=ans+a[i]+add_tag[br];
    return ans;
}
int main()
{
    cin>>n>>m;
    init();
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=m;i++){
        int opt,x,y,k;
        scanf("%d",&opt);
        if(opt==1){
            scanf("%d%d%d",&x,&y,&k);
            add(x,y,k);
        }
        else{
            scanf("%d%d",&x,&y);
            cout<<query(x,y)<<endl;
        }
    }
    return 0;
}

|