제출 #856449

#제출 시각아이디문제언어결과실행 시간메모리
856449hartiksalariaBigger segments (IZhO19_segments)C++17
37 / 100
1143 ms262144 KiB
#include <bits/stdc++.h>
using namespace std;

struct Node {
    int mx;
    Node() {
        mx = -1e9;
    }
    Node(int val) {
        mx = val;
    }
};
struct Seg {
    int n;
    vector<Node> st;
    Node merge(Node &l, Node &r) {
        Node res;
        res.mx = max(l.mx, r.mx);
        return res;
    }
    Seg(int _n) {
        this->n = _n;
        st.assign(4 * _n, Node());
    }
    void update(int l, int r, int x, int val, int node) {
        if (l > x || r < x) {
            return;
        }
        if (l == r) {
            st[node].mx = max(st[node].mx, val);
            return;
        }
        int m = (l + r) / 2;
        update(l, m, x, val, 2 * node + 1);
        update(m + 1, r, x, val, 2 * node + 2);
        st[node] = merge(st[2 * node + 1], st[2 * node + 2]);
    }
    void update(int x, int val) {
        update(0, n - 1, x, val, 0);
    }
    Node query(int start, int end, int l, int r, int node) {
        if (end < l || start > r) {
            return Node();
        }
        if (start >= l && end <= r) {
            return st[node];
        }
        int mid = (start + end) / 2;
        Node left = query(start, mid, l, r, 2 * node + 1);
        Node right = query(mid + 1, end, l, r, 2 * node + 2);
        Node res = merge(left, right);
        return res;
    }
    int query(int l, int r) {
        return query(0, n - 1, l, r, 0).mx;
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, x;
    cin >> n;
    vector<long long> pref(n + 1);
    for (int i = 0; i < n; ++i) {
        cin >> x;
        pref[i + 1] = pref[i] + x;
    }
    auto mx = [&](int l, int r) -> long long {
        return pref[r] - (l ? pref[l - 1] : 0);
    };
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, -1e9));
    vector<Seg> ds(n + 1, Seg(n + 1));
    ds[0].update(0, 0);
    dp[0][0] = 0;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= i; ++j) {
            int low = 0, high = j - 1;
            int best = -1;
            while (low <= high) {
                int mid = (low + high) / 2;
                if (mx(mid, j - 1) <= mx(j, i)) {
                    best = mid;
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
            if (best != -1) {
                dp[i][j] = 1 + ds[j - 1].query(best, j - 1);
                ds[i].update(j, dp[i][j]);
            }
        }
    }
    int ans = 0;
    for (int i = 0; i <= n; ++i) {
        ans = max(ans, dp[n][i]);
    }
    cout << ans << '\n';
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...