chenfy27的刷题记录

导航

CH4301 区间最大子段和

给定长度为N的数组A,以及M条指令,每条指令可能是以下两种之一:

  • 1 x y,查询区间[x,y]中的最大连续子段和。
  • 2 x y,把A[x]改成y。

对于每个询问,输出一个整数表示答案。
数据限制:N<=5e5, M<=1e5, |A[i]|<=1000。

提示:线段树,每个区间需要维护答案、前缀、后缀以及区间和。

#include <bits/stdc++.h>
using i64 = long long;

// SegmentTree模板...

struct Info {
    int val, pre, suf, sum;
    static const int inf = 1e8;
    Info(int v=inf):val(v),pre(v),suf(v),sum(v) {}
    friend Info operator+(const Info &a, const Info &b) {
        if (a.val == inf) {
            return b;
        }
        if (b.val == inf) {
            return a;
        }
        Info ans;
        ans.val = std::max(a.suf + b.pre, std::max(a.val, b.val));
        ans.pre = std::max(a.pre, a.sum+b.pre);
        ans.suf = std::max(a.suf+b.sum, b.suf);
        ans.sum = a.sum + b.sum;
        return ans;
    }
};

void solve() {
    int N, M;
    std::cin >> N >> M;
    std::vector<int> A(N);
    for (int i = 0; i < N; i++) {
        std::cin >> A[i];
    }
    SegmentTree<Info> seg(A);
    for (int i = 0; i < M; i++) {
        int k, x, y;
        std::cin >> k >> x >> y;
        if (k == 1) {
            x--, y--;
            if (x > y) {
                std::swap(x, y);
            }
            std::cout << seg.rangeQuery(x, y+1).val << "\n";
        } else {
            x--;
            seg.modify(x, Info(y));
        }
    }
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

posted on 2024-06-20 21:48  chenfy27  阅读(40)  评论(0)    收藏  举报