是我不配学线段树了

P1253 扶苏的问题

TheSky233 @ 2022-01-07 21:06:15

看到板子题觉得很兴奋,可以水绿题了

然后写了两个小时还是40pts

#include <cstdio>
#define ri register int
#define ls p<<1
#define rs p<<1|1
#define int long long
#define INF 1e10 
using namespace std;

const int N=1e6+5;

struct node{
    int l,r;
    int tag1,tag2;
    int maxn;
}tree[N<<2];

inline int read(){
    int f=1; int num=0;
    char ch=getchar();
    while(ch<'0'||ch>'9'){f=ch=='-'?-1:1;ch=getchar();}
    while(ch>='0'&&ch<='9'){num=(num<<1)+(num<<3)+(ch^48); ch=getchar();}
    return num*f;
}

void write(int x) {
     if(x<0) putchar('-'),x=-x;
     if(x>9) write(x/10);
     putchar(x%10+'0');
}

int max(int a,int b){
    return a>b?a:b;
}

int n,q,op,x,y,z;
int a[N];

void pushup(int p){
    tree[p].maxn=max(tree[ls].maxn,tree[rs].maxn);
}

void pushdown(int p){
    if(tree[p].tag1){
        tree[ls].tag1=tree[rs].tag1=tree[p].tag1;
        tree[ls].maxn=tree[p].tag1;
        tree[rs].maxn=tree[p].tag1;
        tree[ls].tag2=tree[rs].tag2=0;
        tree[p].tag1=0;
    }
    if(tree[p].tag2){
        tree[ls].tag2+=tree[p].tag2;
        tree[rs].tag2+=tree[p].tag2;
        tree[ls].maxn+=tree[p].tag2;
        tree[rs].maxn+=tree[p].tag2;
        tree[p].tag2=0;
    }
}

void build(int p,int l,int r){
    tree[p].l=l;tree[p].r=r;
    if(l==r){
        tree[p].maxn=a[l]; return;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(p);
}

void update1(int p,int l,int r,int delta){
    if(l<=tree[p].l&&tree[p].r<=r){
        tree[p].maxn=delta;
        tree[p].tag1=delta;
        return;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1;
    if(l<=mid) update1(ls,l,r,delta);
    if(r>mid) update1(rs,l,r,delta);
    pushup(p);
}

void update2(int p,int l,int r,int delta){
    if(l<=tree[p].l&&tree[p].r<=r){
        tree[p].maxn+=delta;
        tree[p].tag2+=delta;
        return;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1;
    if(l<=mid) update2(ls,l,r,delta);
    if(r>mid) update2(rs,l,r,delta);
    pushup(p);
}

int qmax(int p,int l,int r){
    if(l<=tree[p].l&&tree[p].r<=r){
        return tree[p].maxn;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1,val=-INF;
    if(l<=mid) val=max(val,qmax(ls,l,r));
    if(r>mid) val=max(val,qmax(rs,l,r));
    return val;
}

signed main(){
    n=read(); q=read();
    for(ri i=1;i<=n;i++) a[i]=read();
    build(1,1,n);
    while(q--){
        op=read();
        if(op==1){
            x=read(); y=read(); z=read();
            update1(1,x,y,z);
        }
        if(op==2){
            x=read(); y=read(); z=read();
            update2(1,x,y,z);
        }
        if(op==3){
            x=read(); y=read();
            write(qmax(1,x,y));
            putchar('\n');
        }
    }
    return 0;
}

by Raymondzll @ 2022-01-07 21:11:59

推平的tag=0时也是有意义的,无意义改成-INF。


by Raymondzll @ 2022-01-07 21:12:12

@TheSky233


by MatrixGroup @ 2022-01-07 21:21:41

@TheSky233 初始化


by TheSky233 @ 2022-01-07 21:23:03

@Raymondzll 改了之后50pts了


void pushdown(int p){
    if(tree[p].tag1!=-INF){
        tree[ls].tag1=tree[rs].tag1=tree[p].tag1;
        tree[ls].maxn=tree[p].tag1;
        tree[rs].maxn=tree[p].tag1;
        tree[ls].tag2=tree[rs].tag2=0;
        tree[p].tag1=-INF;
    }
    if(tree[p].tag2){
        tree[ls].tag2+=tree[p].tag2;
        tree[rs].tag2+=tree[p].tag2;
        tree[ls].maxn+=tree[p].tag2;
        tree[rs].maxn+=tree[p].tag2;
        tree[p].tag2=0;
    }
}

void build(int p,int l,int r){
    tree[p].l=l;tree[p].r=r; tree[p].tag1=-INF;
    if(l==r){
        tree[p].maxn=a[l]; return;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(p);
}

by 无咕_ @ 2022-01-07 21:30:17

@TheSky233 tree开大点呢


by StarLbright40 @ 2022-01-07 21:45:40

@TheSky233 你 update1 没清 tag2


by 无咕_ @ 2022-01-07 21:49:20

和 这个 很像啊 P4315


by Raymondzll @ 2022-01-07 21:49:25

@TheSky233

void update1(int p,int l,int r,int delta){
    if(l<=tree[p].l&&tree[p].r<=r){
        tree[p].maxn=delta;
        tree[p].tag1=delta;
        tree[p].tag2=0;//here.
        return;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1;
    if(l<=mid) update1(ls,l,r,delta);
    if(r>mid) update1(rs,l,r,delta);
    pushup(p);
}

by 无咕_ @ 2022-01-07 21:49:45

双tag一生之敌


by Raymondzll @ 2022-01-07 21:56:12

这种双tag的就单独写一个 void cover(int id,int c){...}这样的吧,像莫队那种写多了就成习惯了。


| 下一页