线段树wa求调

P1253 扶苏的问题

Q__A__Q @ 2023-07-19 23:40:14

代码:

// Problem: P1253 扶苏的问题
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Author: fzy
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
// #pragma GCC optimize(2)
using namespace std;
typedef long long ll;
#define int ll

const int maxn=1e6+10;
const int inf=1e9+7;
int n,m,ans,a[maxn],mx[maxn<<2],cover[maxn<<2],add[maxn<<2];

inline int read() {
    int s=0,w=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-')w=-1;
        ch=getchar();
    }
    while(isdigit(ch)) s=s*10+ch-'0',ch=getchar();
    return s*w;
}

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

inline void pushup(int rt) {
    mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
}

inline void build(int rt,int l,int r) {
    if(l==r) {
        mx[rt]=a[l];
        return;
    }
    int m=(l+r)>>1;
    build(rt<<1,l,m);
    build(rt<<1|1,m+1,r);
    pushup(rt);
}

inline void pushdown(int rt) {
    if(cover[rt]!=inf) {
        mx[rt<<1]=cover[rt];
        mx[rt<<1|1]=cover[rt];
        cover[rt<<1]=cover[rt];
        cover[rt<<1|1]=cover[rt];
        cover[rt]=inf;
        add[rt<<1]=0;
        add[rt<<1|1]=0;
    }
    if(add[rt]) {
        mx[rt<<1]+=add[rt];
        mx[rt<<1|1]+=add[rt];
        add[rt<<1]+=add[rt];
        add[rt<<1|1]+=add[rt];
        add[rt]=0;
    }
}

inline void update1(int l,int r,int x,int y,int c,int rt) {
    if(l>=x&&r<=y) {
        mx[rt]=c;
        add[rt]=0;
        cover[rt]=c;
        return;
    }
    int m=(l+r)>>1;
    pushdown(rt);
    if(x<=m) update1(l,m,x,y,c,rt<<1);
    if(y>m) update1(m+1,r,x,y,c,rt<<1|1);
    pushup(rt);
}

inline void update2(int l,int r,int x,int y,int c,int rt) {
    if(l>=x&&r<=y) {
        mx[rt]+=c;
        add[rt]+=c;
        return;
    }
    int m=(l+r)>>1;
    pushdown(rt);
    if(x<=m) update2(l,m,x,y,c,rt<<1);
    if(y>m) update2(m+1,r,x,y,c,rt<<1|1);
    pushup(rt);
}

inline int query(int l,int r,int x,int y,int rt) {
    if(l>=x&&r<=y) {
        return mx[rt];
    }
    int m=(l+r)>>1,tot=-inf;
    pushdown(rt);
    if(x<=m) tot=max(tot,query(l,m,x,y,rt<<1));
    if(y>m) tot=max(tot,query(m+1,r,x,y,rt<<1|1));
    return tot;
}

signed main() {
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;++i) a[i]=read();
    build(1,1,n);
    for(int i=1;i<=n;++i) cover[i]=inf;
    while(m--) {
        int opt=read();
        if(opt==1) {
            int l=read(),r=read(),x=read();
            update1(1,n,l,r,x,1);
        }
        else if(opt==2) {
            int l=read(),r=read(),x=read();
            update2(1,n,l,r,x,1);
        }
        else {
            int l=read(),r=read();
            write(query(1,n,l,r,1));
            puts("");
        }
    }
    // for(int i=1;i<=n;++i)
        // cout<<query(1,n,i,i,1)<<endl;
    return 0;
}

|