9pts WA求助,样例过了

P4513 小白逛公园

5t0_0r2 @ 2023-08-30 16:24:11

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N = 1e5 + 9,ROOT = 1,INF = 1e9 + 9;
int a[N];
struct seg_tree{
    struct node {
        int val,sum,lsum,rsum,change;
    } tree[N << 2];
    bool in_range(int l,int r,int now_l,int now_r){
        return l <= now_l && now_r <= r;
    }
    bool out_range(int l,int r,int now_l,int now_r){
        return now_r < l || now_l > r;
    }
    int len(int l,int r){
        return r - l + 1;
    }
    void push_up(int root){
        int lchild = root * 2,rchild = root * 2 + 1;
        tree[root].sum = tree[lchild].sum + tree[rchild].sum;
        tree[root].val = max(max(tree[lchild].val,tree[rchild].val),tree[lchild].rsum + tree[rchild].lsum);
        tree[root].lsum = max(tree[lchild].lsum,tree[lchild].sum + tree[rchild].lsum);
        tree[root].rsum = max(tree[rchild].rsum,tree[rchild].sum + tree[lchild].rsum);
    }
    void make_tag(int Len,int root,int change){
        tree[root].change = change;
        tree[root].val = tree[root].sum = tree[root].lsum = tree[root].rsum = Len * change;
    }
    void push_down(int l,int r,int root){
        int mid = (l + r) / 2,lchild = root * 2,rchild = root * 2 + 1;
        if(tree[root].change != INF){
            make_tag(len(l,mid),lchild,tree[root].change);
            make_tag(len(mid + 1,r),rchild,tree[root].change);
            tree[root].change = INF;
        }
    }
    void build(int l,int r,int root) {
        tree[root].change = INF;
        if(l == r) {
            tree[root].val = tree[root].sum = tree[root].lsum = tree[root].rsum = a[l];
            return;
        }
        int mid = (l + r) / 2,lchild = root * 2,rchild = root * 2 + 1;
        build(l,mid,lchild);
        build(mid + 1,r,rchild);
        push_up(root);
    }
    void update(int l,int r,int now_l,int now_r,int root,int change) {
        if(in_range(l,r,now_l,now_r))
            make_tag(len(l,r),root,change);
        else if(!out_range(l,r,now_l,now_r)){
            int mid = (now_l + now_r) / 2,lchild = root * 2,rchild = root * 2 + 1;
            push_down(now_l,now_r,root);
            update(l,r,mid + 1,now_r,rchild,change);
            update(l,r,now_l,mid,lchild,change);
            push_up(root);
        }
        return;
    }
    int getsum(int l, int r, int now_l, int now_r, int root) {
        int mid = (now_l + now_r) / 2,lchild = root * 2,rchild = root * 2 + 1;
        if(in_range(l,r,now_l,now_r))
            return tree[root].val;
        else if(!out_range(l,r,now_l,now_r)){
            push_down(now_l,now_r,root);
            return max(getsum(l,r,now_l,mid,lchild),getsum(l,r,mid + 1,now_r,rchild));
        }
        else
            return -INF;
    }
} seg;
int n,m;
int op,x,y,k;
signed main() {
    scanf("%lld%lld", &n, &m);
    for(int i = 1; i <= n; i++)
        scanf("%lld", &a[i]);
    seg.build(1,n,ROOT);
    for(int i = 1; i <= m; i++) {
        scanf("%lld%lld%lld", &op, &x, &y);
        if(op == 1){
            if(x > y)
                swap(x,y);
            printf("%lld\n",seg.getsum(x,y,1,n,ROOT));
        }
        else
            seg.update(x,x,1,n,ROOT,y);
    }
}

by 5t0_0r2 @ 2023-08-30 16:24:37

打错了,N 是 5e5 + 9


by Michaellg @ 2023-08-30 16:34:39

@5t0_0r2 getsum 的合并要和 pushup 一样,不能直接取 max,要将 getsum 返回值变成 node。

return Node {
    max(max(L.ms, R.ms), L.rms + R.lms),
    L.s + R.s,
    max(L.lms, L.s + R.lms),
    max(R.rms, R.s + L.rms)
};

by 5t0_0r2 @ 2023-08-30 16:38:34

@Michaellg 能结合我的代码告诉我吗(好多变量我都没看懂什么意思)


by Michaellg @ 2023-08-30 16:41:44

@5t0_0r2 ms,s,lms,rms 分别对应 val,sum,lsum,rsum


by 5t0_0r2 @ 2023-08-30 16:44:29

@Michaellg 那 L 和 R 呢?左右子节点?


by Michaellg @ 2023-08-30 16:45:06

@5t0_0r2 还要注意线段树 getsum 时如果子节点被递归了两次,复杂度会炸掉,所以要把子节点递归结果先记录下来


by Michaellg @ 2023-08-30 16:45:44

L 和 R 就是子节点的结果


by 5t0_0r2 @ 2023-08-30 17:01:27

@Michaellg

    node getsum(int l, int r, int now_l, int now_r, int root) {
        int mid = (now_l + now_r) / 2,lchild = root * 2,rchild = root * 2 + 1;
        if(in_range(l,r,now_l,now_r))
            return tree[root];
        else if(!out_range(l,r,now_l,now_r)){
            push_down(now_l,now_r,root);
            node L = getsum(l,r,now_l,mid,lchild),R = getsum(l,r,mid + 1,now_r,rchild);
            return
            (node){
                L.sum + R.sum,
                max(max(L.val,R.val),L.rsum + R.lsum),
                max(L.lsum,L.sum + R.lsum),
                max(R.rsum,R.sum + L.rsum),
                tree[root].change
            };
        }
    }

这样吗?现在爆零了


by Michaellg @ 2023-08-30 17:05:30

@5t0_0r2 L.sum + R.sum 和 max(max(L.val,R.val),L.rsum + R.lsum 写反了


by 5t0_0r2 @ 2023-08-30 17:09:10

@Michaellg 还是爆零


| 下一页