7/10段树求调

P3372 【模板】线段树 1

Kiw_ @ 2024-07-20 07:09:23

70分WA

#include<bits/stdc++.h>
using namespace std;
long long a[100005],d[400005],b[400005],n,m,ques,x,y,k;
void build(long long s,long long t,long long p)
{
    if(s==t)
    {
        d[p]=a[s];
        return;
    }
    long long m=s+((t-s)>>1);
    build(s,m,p<<1);
    build(m+1,t,(p<<1)+1);
    d[p]=d[p<<1]+d[(p<<1)+1];
    return;
}
void update(long long l,long long r,long long c,long long s,long long t,long long p)
{
    if(l<=s&&r>=t)
    {
        b[p]+=c;
        d[p]+=c*(t-s+1);
        return;
    }
    long long m=s+((t-s)>>1);
    if(b[p]&&s!=t)
    {
        b[p<<1]+=b[p];
        b[(p<<1)+1]+=b[p];
        d[p<<1]+=b[p]*(m-s+1);
        d[(p<<1)+1]+=b[p]*(t-m);
        b[p]=0;
    }
    if(l<=m)
    {
        update(l,r,c,s,m,(p<<1));
    }
    if(r>m)
    {
        update(l,r,c,m+1,t,(p<<1)+1);
    }
    d[p]=d[p<<1]+d[(p<<1)+1];
}
int getsum(long long l,long long r,long long s,long long t,long long p)
{
    if(l<=s&&r>=t)
    {
        return d[p];
    }
    long long m=s+((t-s)>>1);
    if(b[p])
    {
        d[p<<1]+=b[p]*(m-s+1);
        d[(p<<1)+1]+=b[p]*(t-m);
        b[p<<1]+=b[p];
        b[(p<<1)+1]+=b[p];
        b[p]=0;
    }
    long long sum=0;
    if(l<=m)
        sum+=getsum(l,r,s,m,p*2);
    if(r>m)
        sum+=getsum(l,r,m+1,t,p*2+1);
    return sum;
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for(long long i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }
    build(1,n,1);
    for(long long i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&ques,&x,&y);
        if(ques==1)
        {
            scanf("%lld",&k);
            update(x,y,k,1,n,1);
        }
        if(ques==2)
        {
            printf("%lld\n",getsum(x,y,1,n,1));
        }
    }
    return 0;
}

by HZHDCM @ 2024-07-20 07:41:07


by YQD_Q @ 2024-07-20 07:44:40

@kiwen761421 建议写结构体存树,检查一下push_down是否正确,下次询问代码时最好加点注释 调了两次从70调到10分 跳楼了


by qazsedcrfvgyhnujijn @ 2024-07-20 07:56:59

建议把找左儿子,找右儿子,pushuppushdown 全部写成函数,简单明了

#define ls(u) (u << 1)
#define rs(u) (u << 1 | 1)
void pushup(int u) {
  d[u] = d[ls(u)] + d[rs(u)];
}
void pushdown(int u) {
    ...
}

by Handezheng @ 2024-07-20 07:59:53

@YQD_Q
不要把题解发到讨论区


by lcfollower @ 2024-07-20 08:19:53

@kiwen761421 \operatorname{getnum} 返回 long long 不是 int


by Kiw_ @ 2024-07-20 13:34:55

@lcfollower 已过,感谢大佬!


by Kiw_ @ 2024-07-20 13:35:08

@HZHDCM 已过,感谢大佬!


|