6-10wa(哭

P1253 扶苏的问题

陈asuna @ 2024-02-27 00:58:05

一般来说,6-10是因为负值的原因,但是我觉得我的负值开的够小来着。本人刚学几星期的菜鸡,有无大佬帮帮忙来着,感谢

#include<bits/stdc++.h>
using namespace std;
#define lc p*2
#define rc p*2+1
#define ll long long
const ll INF =0x3f3f3f3f3f3f3f3f;

const int N=1e7+20;
struct node
{
    ll l,r,maxn,add1,add2,flag;
}tr[4*N];
ll w[N];

void pushup(ll p)
{
    //cout<<"lc "<<lc<<" "<<tr[lc].maxn<<" rc "<<rc<<" "<<tr[rc].maxn<<endl;
    tr[p].maxn=max(tr[lc].maxn,tr[rc].maxn);
    //cout<<"p "<<p<<endl;
}

void build(ll p,ll l,ll r)
{
    tr[p]={l,r,w[l],0};
    tr[p].flag=0;
    if(l==r) return;
    ll m=l+r>>1;
    build(lc,l,m);
    build(rc,m+1,r);
    pushup(p);
}

void pushdown2(ll p)
{
    if(tr[p].flag)
    {
        tr[lc].flag=tr[p].flag;
        tr[rc].flag=tr[p].flag;
        tr[lc].maxn=tr[p].add2;
        tr[rc].maxn=tr[p].add2;
        tr[p].flag=0;
        tr[p].add1=tr[lc].add1=tr[rc].add1=0;
    }
}

void pushdown1(ll p)
{
    pushdown2(p);
    if(tr[p].add1)
    {
        tr[lc].add1+=tr[p].add1;
        tr[rc].add1+=tr[p].add1;
        tr[lc].maxn+=tr[p].add1;
        tr[rc].maxn+=tr[p].add1;
        tr[p].add1=0;
    }
}

void update1(ll p,ll x,ll y,ll k)
{

    //cout<<"p1 "<<p<<" "<<tr[p].maxn<<" "<<x<<y<<tr[p].l<<tr[p].r<<endl;
    if(x<=tr[p].l&&tr[p].r<=y)
    {
        //cout<<p<<endl;
        tr[p].maxn+=k;
        tr[p].add1+=k;
        return;
    }
    ll m=tr[p].l+tr[p].r>>1;
    pushdown2(p);
    pushdown1(p);

    if(x<=m) update1(lc,x,y,k);
    if(m<y) update1(rc,x,y,k);
    pushup(p);
}

void update2(ll p,ll x,ll y,ll k)
{
    if(x<=tr[p].l&&tr[p].r<=y)
    {
        tr[p].maxn=k;
        //cout<<p<<" "<<tr[p].maxn<<endl;
        tr[p].flag=1;
        tr[p].add2=k;
        return;
    }
    ll m=tr[p].l+tr[p].r>>1;

    pushdown2(p);
    pushdown1(p);
    if(x<=m) update2(lc,x,y,k);
    if(m<y) update2(rc,x,y,k);
    pushup(p);
}

ll query(ll p,ll x,ll y)
{
    if(x<=tr[p].l&&tr[p].r<=y)
    {
        //cout<<p<<" "<<tr[p].maxn<<endl;
        return tr[p].maxn;
    }
    int m=tr[p].l+tr[p].r>>1;
    ll maxn=-INF;
    pushdown2(p);
    pushdown1(p);
    if(x<=m) maxn=max(maxn,query(lc,x,y));
    if(y>m) maxn=max(maxn,query(rc,x,y));
    pushup(p);
    return maxn;
}

int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&w[i]);
    }
    build(1,1,n);
    while(m--)
    {
        int op;
        scanf("%d",&op);
        if(op==1)
        {
            ll l,r,x;
            scanf("%lld%lld%lld",&l,&r,&x);
            update2(1,l,r,x);
        }
        else if(op==2)
        {
            ll l,r,x;
            scanf("%lld%lld%lld",&l,&r,&x);
            update1(1,l,r,x);
        }
        else if(op==3)
        {
            ll l,r;
            scanf("%lld%lld",&l,&r);
            printf("%d\n",query(1,l,r));
        }
    }
    return 0;
}

by UMS2 @ 2024-02-27 07:15:37

pushdown2内不要把p的add1归零。

考虑先覆盖再加,你的pushdown2会把加的标记抹掉。


by UMS2 @ 2024-02-27 07:21:17

update1内覆盖时要将加的标记消除。

并且里面pushdown2可以删掉,你的pushdown1里面已经有了。


by UMS2 @ 2024-02-27 07:23:30

query里没有必要pushup,此外应该没啥问题 @陈asuna


by UMS2 @ 2024-02-27 07:29:32

优化的话可以把覆盖和加单独做成两个函数,这样 pushdown 和 update 的时候直接调用。

可以把 pushdown2 并到 pushdown1 里用两个 if 并列。

flag 和 add2可以写成一个,把 add2 默认值设置成 inf 就可以实现。


by UMS2 @ 2024-02-27 07:35:57

build 里面,应该是要到 l==r 时再赋值,不应该直接赋值。

void build(int k,int l,int r){
    line[k].l=l,line[k].r=r;
    line[k].upt=inf;
    if(l==r){
        line[k].val=w[l];
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    kp(k);
}

by 陈asuna @ 2024-02-27 11:45:24

@UMS2 感谢大佬,已经AC!其实最后那个op==3写错了,应该是printf("%lld\n"...),改了前头忘改后头了


|