70分求调教

P3372 【模板】线段树 1

iikunkun @ 2023-10-10 20:46:42

#include<bits/stdc++.h>
using namespace std;
long long b[200001];
long long a[200001];
long long lazy[400001];
void build(int u,int l,int r)
{
    if(l==r)
    a[u]=b[l];
    else
    {
        int m=(l+r)/2;
        build(u*2,l,m);
        build(u*2+1,m+1,r);
        a[u]=a[u*2]+a[u*2+1];
    }
    return;
}
void maketag(int u,int l,int r,int tag)
{
    a[u]+=((r-l+1)*tag);
    lazy[u]+=tag;
    return;
}
void pushdown(int u,int l,int r)
{
    int m=(l+r)/2;
    if(l==r)
    {
        lazy[u]=0;
        return;
    }
    maketag(u*2,l,m,lazy[u]);
    maketag(u*2+1,m+1,r,lazy[u]);
    lazy[u]=0;
    return;
}
long long query(int u,int l,int r,int ll,int rr)
{
    int m=(l+r)/2;
    if(ll<=l&&rr>=r)
    return a[u];
    else if(!(ll>r||rr<l))
    {
        pushdown(u,l,r);
        return query(u*2,l,m,ll,rr)+query(u*2+1,m+1,r,ll,rr);
    }
    else
    return 0;   
}
void update(int u,int l,int r,int ll,int rr,int x)
{
    int m=(l+r)/2;
    if(ll<=l&&rr>=r)
    {
        a[u]+=((r-l+1)*x);
        lazy[u]+=x;
    }
    else if(!(ll>r||rr<l))
    {
        pushdown(u,l,r);
        update(u*2,l,m,ll,rr,x);
        update(u*2+1,m+1,r,ll,rr,x);
        a[u]=a[u*2]+a[u*2+1];
    }
    return;
}
int main()
{
    long long n,m,i,j;
    cin>>n>>m;
    for(i=1;i<=n;i++)
    cin>>b[i];
    build(1,1,n);
    long long op,x,y,k;
    for(i=1;i<=m;i++)
    {
        cin>>op;
        if(op==1)
        {
            cin>>x>>y;
            scanf("%lld",&k);
            update(1,1,n,x,y,k);
        }
        else
        {
            cin>>x>>y;
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}

by mori_ @ 2023-10-10 23:38:25

您的数组开太小了

开两倍后 已经通过: 链接

求关:)


by mori_ @ 2023-10-10 23:38:58

@iikunkun


by iikunkun @ 2023-10-12 19:50:46

@mori_ 谢谢!


|