样例第三个求和输出18,应为20,求帮助

P3372 【模板】线段树 1

xuxinyi @ 2023-02-06 18:42:19

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int a[N];
struct node
{
    int l,r;
    int sum;
    int lazy=0;
}
d[N*4];
void pushdown(int p)
{
    d[2*p].lazy+=d[p].lazy;
    d[2*p+1].lazy+=d[p].lazy;
    d[2*p].sum+=d[p].lazy;
    d[2*p+1].sum+=d[p].lazy;
    d[p].lazy=0;
}
void build(int l,int r,int p)
{
    d[p].l=l;
    d[p].r=r;
    d[p].lazy=0;
    if(l==r)
    {
        d[p].sum=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,2*p);
    build(mid+1,r,2*p+1);
    d[p].sum=d[2*p].sum+d[2*p+1].sum;
    return;
}
void print(int p)
{
    if(d[p].l==d[p].r)
    {
        cout<<p<<endl;
        cout<<d[p].l<<" "<<d[p].r<<endl;
        cout<<d[p].sum<<endl;
        cout<<endl;
        return;
    }
    else
    {
        cout<<p<<endl;
        cout<<d[p].l<<" "<<d[p].r<<endl;
        cout<<d[p].sum<<endl;
        cout<<endl;
        print(2*p);
        print(2*p+1);
    }

}
void update(int l,int r,int k,int p)
{
    if(d[p].l==d[p].r)
    {
        d[p].sum+=k;
        return;
    }
    else if(l<=d[p].l && d[p].r<=r)
    {
        d[p].sum+=k;
        d[p].lazy+=k;
        return;
    }
    int mid=(d[p].l+d[p].r)>>1;

    if(l<=mid) update(l,r,k,2*p);
    if(r>mid) update(l,r,k,2*p+1);
    pushdown(p);
    d[p].sum=d[2*p].sum+d[2*p+1].sum;
    return;

}
long long getsum(int l,int r,int p)
{

    if(l<=d[p].l && d[p].r<=r)
    {
        return d[p].sum;
    }

    long long mid=(d[p].l+d[p].r)>>1;
    pushdown(p);

    if(l>mid) return getsum(l,r,2*p+1);
    if(r<=mid) return getsum(l,r,2*p);

    return getsum(l,r,2*p+1)+getsum(l,r,2*p);

}
void Merge(int p)
{
    if(d[p].l==d[p].r)
    {
        return;
    }
    else
    {
        d[p].sum=d[2*p].sum+d[2*p+1].sum;
        Merge(2*p);
        Merge(2*p+1);
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        int tot;
        cin>>tot;
        if(tot==1)
        {
            int l,r,k;
            cin>>l>>r>>k;
            update(l,r,k,1);
            Merge(1);
        //  print(1);
        }
        else if(tot==2)
        {
            int l,r;
            cin>>l>>r;
            Merge(1);
            cout<<getsum(l,r,1)<<endl;
        }
    }
    return 0;
}

如果不想看这么长的话,请各位大佬在以下几个函数里帮帮忙 我认为问题很大可能出现在这几个函数里

void update(int l,int r,int k,int p)
{
    if(d[p].l==d[p].r)
    {
        d[p].sum+=k;
        return;
    }
    else if(l<=d[p].l && d[p].r<=r)
    {
        d[p].sum+=k;
        d[p].lazy+=k;
        return;
    }
    int mid=(d[p].l+d[p].r)>>1;

    if(l<=mid) update(l,r,k,2*p);
    if(r>mid) update(l,r,k,2*p+1);
    pushdown(p);
    d[p].sum=d[2*p].sum+d[2*p+1].sum;
    return;

}
void build(int l,int r,int p)
{
    d[p].l=l;
    d[p].r=r;
    d[p].lazy=0;
    if(l==r)
    {
        d[p].sum=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,2*p);
    build(mid+1,r,2*p+1);
    d[p].sum=d[2*p].sum+d[2*p+1].sum;
    return;
}
long long getsum(int l,int r,int p)
{

    if(l<=d[p].l && d[p].r<=r)
    {
        return d[p].sum;
    }

    long long mid=(d[p].l+d[p].r)>>1;
    pushdown(p);

    if(l>mid) return getsum(l,r,2*p+1);
    if(r<=mid) return getsum(l,r,2*p);

    return getsum(l,r,2*p+1)+getsum(l,r,2*p);

}

by William_Wang_ @ 2023-02-06 18:47:13

@xuxinyi


by William_Wang_ @ 2023-02-06 18:54:59

区间加的懒标记下放到左右区间 , 左右区间加的量分别是 tag*(mid-l+1)tag*(r-mid)


by xuxinyi @ 2023-02-06 19:01:15

@UFO2007 谢谢,也就是说要改pushdown吗?


by William_Wang_ @ 2023-02-06 19:05:12

@xuxinyi pushdownupdate


by xuxinyi @ 2023-02-06 19:07:54

@UFO2007 谢谢!通过了!


|