悬赏关注

P3372 【模板】线段树 1

Dreamer_OI @ 2024-02-23 22:13:33

WA,0pts求助

#include<bits/stdc++.h>
using namespace std;
int l[400010],r[400010],len[400010];
long long a[400010],sum[400010],add[400010];
void build(int id,int L,int R)
{
    l[id]=L;
    r[id]=R;
    len[id]=R-L+1;
    cout<<l[id]<<" "<<r[id]<<" "<<len[id]<<endl;
    if(L==R)
    {
        sum[id]=a[L];
    }
    else
    {
        int mid=(L+R)>>1;
        build(id*2,L,mid);
        build(id*2+1,mid+1,R);
        sum[id]=sum[id*2]+sum[id*2+1];
    }
}
void solve(int id)
{
    int lc=id*2,rc=id*2+1;
    if(l[id]<r[id])
    {
        sum[id]=sum[lc]+sum[rc];
    }
    sum[id]+=add[id]*len[id];
}
void update(int id,int S,int T,long long num)
{
    int lc=id*2,rc=id*2+1;
    if(S<=l[id]  &&  r[id]<=T)
    {
        add[id]+=num;
    }
    else
    {
        if(S<=r[lc])
        {
            update(lc,S,r[lc],num);
        }
        if(T>=l[rc])
        {
            update(rc,l[rc],T,num);
        }
    }
    solve(id);
}
long long query(int id,int S,int T,long long num)
{
    int lc=id*2,rc=id*2+1;
    if(S<=l[id]  &&  r[id]<=T)
    {
        return sum[id]+num*len[id];
    }
    else
    {
        long long ans=0LL;
        if(S<=r[lc])
        {
            ans+=query(lc,S,r[lc],num+add[id]);
        }
        if(T>=l[rc])
        {
            ans+=query(rc,l[rc],T,num+add[id]);
        }
        return ans;
    }
}
int main()
{
    int n,q;
    scanf("%d %d",&n,&q);
    for(int i=1; i<=n; i++)
    {
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    while(q--)
    {
        int cmd;
        scanf("%d",&cmd);
        if(cmd==1)
        {
            int s,t;
            long long num;
            scanf("%d %d %lld",&s,&t,&num);
            update(1,s,t,num);
        }
        else
        {
            int s,t;
            scanf("%d %d",&s,&t);
            printf("%lld\n",query(1,s,t,0LL));
        }
    }
    return 0;
}

by Lizichen_licis @ 2024-02-24 10:04:05

你得用多点修改,打懒标记。


by Lizichen_licis @ 2024-02-24 10:04:47

具体可以参考一下我的:

void maketag(int u,int len,long long val)
{
    lzy[u]+=val;
    w[u]+=len*val;
}
void pushdown(int u,int L,int R)
{
    int mid=(L+R)/2;
    maketag(2*u,mid-L+1,lzy[u]);
    maketag(2*u+1,R-mid,lzy[u]);
    lzy[u]=0;
}
void LRupdate(int u,int L,int R,int l,int r,long long val)
{
    if(inRange(L,R,l,r)) maketag(u,R-L+1,val);
    else if(!outofRange(L,R,l,r))
    {
        int mid=(L+R)/2;
        pushdown(u,L,R);
        LRupdate(2*u,L,mid,l,r,val);
        LRupdate(2*u+1,mid+1,R,l,r,val);
        pushup(u);
    }
}

by Lizichen_licis @ 2024-02-24 10:05:50

其他函数用你自己的就行了


by Dreamer_OI @ 2024-02-25 10:16:34

Thanks.


|