60pts求调

P1253 扶苏的问题

DungeonMasterVan @ 2024-08-23 10:55:43

如题

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1145141;
int a[N],maxn[N*4],n,m,k;
struct node
{
    int maxn,tag,tag1,p;
}tr[N*4];
void build(int root,int l,int r)
{
    tr[root].tag=tr[root].p=tr[root].tag1=0;
    if(l==r) tr[root].maxn=a[l];
    else 
    {
        int mid=(l+r)>>1;
        build(root*2,l,mid);
        build(root*2+1,mid+1,r);
        tr[root].maxn=max(tr[root*2].maxn,tr[root*2+1].maxn);
    }
}
void pushdown(int root,int l,int r)
{
    if(tr[root].p)
    {
        tr[root*2].maxn=tr[root].tag1,tr[root*2+1].maxn=tr[root].tag1;
        tr[root*2].tag1=tr[root].tag1,tr[root*2+1].tag1=tr[root].tag1;
        tr[root*2].p=tr[root*2+1].p=1;
        tr[root].p=tr[root].tag1=0;
    }
    if(tr[root].tag)
    {
        tr[root*2].tag+=tr[root].tag,tr[root*2+1].tag+=tr[root].tag;
        tr[root*2].maxn+=tr[root].tag,tr[root*2+1].maxn+=tr[root].tag;
        tr[root].tag=0;
    }
}
int query(int root,int ql,int qr,int l,int r)
{
    int ans=-1e16;
    if(ql<=l&&r<=qr) return tr[root].maxn;
    int mid=(l+r)>>1;
    pushdown(root,l,r);
    if(ql<=mid) ans=query(root*2,ql,qr,l,mid);
    if(qr>mid) ans=max(ans,query(root*2+1,ql,qr,mid+1,r));
    return ans;
}
void update1(int root,int ul,int ur,int l,int r,int add)
{
    if(l>=ul&&r<=ur)
    {
        tr[root].tag1=add;
        tr[root].p=1;
        tr[root].tag=0;
        tr[root].maxn=add;
        return ;
    }
    pushdown(root,l,r);
    int mid=(l+r)>>1;
    if(ul<=mid) update1(root*2,ul,ur,l,mid,add);
    if(ur>mid) update1(root*2+1,ul,ur,mid+1,r,add);
}
void update2(int root,int ul,int ur,int l,int r,int add)
{
    if(l>=ul&&r<=ur)
    {
        tr[root].tag+=add,tr[root].maxn+=add;
        return ; 
    }
    pushdown(root,l,r);
    int mid=(l+r)>>1;
    if(ul<=mid) update2(root*2,ul,ur,l,mid,add);
    if(ur>mid) update2(root*2+1,ul,ur,mid+1,r,add);
    tr[root].maxn=max(tr[root*2].maxn,tr[root*2+1].maxn);
}
signed main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    build(1,1,n);
    while(m--)
    {
        int pd,x,y;
        scanf("%lld%lld%lld",&pd,&x,&y);
        if(pd==1)
        {
            scanf("%lld",&k);
            update1(1,x,y,1,n,k);
        }
        else if(pd==2)
        {
            scanf("%lld",&k);
            update2(1,x,y,1,n,k);
        }
        else printf("%lld\n",query(1,x,y,1,n));
    }
}

by roger_yrj @ 2024-08-24 09:14:09

建议写一个 push_up

...,,,...,,,,,


by roger_yrj @ 2024-08-24 09:55:40

$28$ 行是你下传覆盖标记时要将儿子的加法标记清空(显然) $63$ 行是忘记上传的低级错误。 ```cpp #include<bits/stdc++.h> #define int long long using namespace std; const int N=1145141; int a[N],n,m,k; struct node { int maxn,tag,tag1,p; }tr[N*4]; void build(int root,int l,int r) { tr[root].tag=tr[root].p=tr[root].tag1=0; if(l==r) tr[root].maxn=a[l]; else { int mid=(l+r)>>1; build(root*2,l,mid); build(root*2+1,mid+1,r); tr[root].maxn=max(tr[root*2].maxn,tr[root*2+1].maxn); } } void pushdown(int root,int l,int r) { if(tr[root].p) { tr[root*2].maxn=tr[root].tag1,tr[root*2+1].maxn=tr[root].tag1; tr[root*2].tag1=tr[root].tag1,tr[root*2+1].tag1=tr[root].tag1; tr[root*2].tag=tr[root*2+1].tag=0;//,,,...,,,..... tr[root*2].p=tr[root*2+1].p=1; tr[root].p=tr[root].tag1=0; } if(tr[root].tag) { tr[root*2].tag+=tr[root].tag,tr[root*2+1].tag+=tr[root].tag; tr[root*2].maxn+=tr[root].tag,tr[root*2+1].maxn+=tr[root].tag; tr[root].tag=0; } } int query(int root,int ql,int qr,int l,int r) { int ans=-1e16; if(ql<=l&&r<=qr) return tr[root].maxn; int mid=(l+r)>>1; pushdown(root,l,r); if(ql<=mid) ans=query(root*2,ql,qr,l,mid); if(qr>mid) ans=max(ans,query(root*2+1,ql,qr,mid+1,r)); return ans; } void update1(int root,int ul,int ur,int l,int r,int add) { if(l>=ul&&r<=ur) { tr[root].tag1=add; tr[root].p=1; tr[root].tag=0; tr[root].maxn=add; return ; } pushdown(root,l,r); int mid=(l+r)>>1; if(ul<=mid) update1(root*2,ul,ur,l,mid,add); if(ur>mid) update1(root*2+1,ul,ur,mid+1,r,add); tr[root].maxn=max(tr[root*2].maxn,tr[root*2+1].maxn);//,,,...,,,..... } void update2(int root,int ul,int ur,int l,int r,int add) { if(l>=ul&&r<=ur) { tr[root].tag+=add,tr[root].maxn+=add; return ; } pushdown(root,l,r); int mid=(l+r)>>1; if(ul<=mid) update2(root*2,ul,ur,l,mid,add); if(ur>mid) update2(root*2+1,ul,ur,mid+1,r,add); tr[root].maxn=max(tr[root*2].maxn,tr[root*2+1].maxn); } signed main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,1,n); while(m--) { int pd,x,y; scanf("%lld%lld%lld",&pd,&x,&y); if(pd==1) { scanf("%lld",&k); update1(1,x,y,1,n,k); } else if(pd==2) { scanf("%lld",&k); update2(1,x,y,1,n,k); } else printf("%lld\n",query(1,x,y,1,n)); } } ```

by roger_yrj @ 2024-08-24 10:07:11

这边建议养成的好习惯。

  1. root*2 改成 root<<1root*2+1 改成 root<<1|1,常数优化显著。

  2. 尝试使用 define:用 ls 代替 tr[root*2],用 rs 代替 tr[root*2+1],这可以减少码量。

  3. pushup 函数:当需要上传的东西多了之后,写 pushup 函数会很方便地上传。

  4. 可以在 build 中提前处理每个段的左端点和右端点,这样递归时就不用重新计算左右端点,使代码清晰美观。

  5. root 四个字母太长了,建议换成 kx,更方便。

  6. #define int long long 不是好习惯,有些题目会因此 MLE


by DungeonMasterVan @ 2024-08-24 14:36:48

@roger_yrj 感谢感谢


by roger_yrj @ 2024-08-24 15:08:48

@DungeonMasterVan 下次有问题直接找我,都是同学:)


|