Submission #1205008

#TimeUsernameProblemLanguageResultExecution timeMemory
1205008ofozBigger segments (IZhO19_segments)C++17
100 / 100
208 ms31932 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pi pair<int, int>
#define vi vector<int>
vector<int> a;
vector<int> prfx;
vector<int> tree;
/*
sum(j+1, i) >= a_j
sum(j+1, i) - a_j >= 0
sum(j+1, i) - a_j - sum(0, i) >= -sum(0, i)
-sum(0, j) - a_j >= -sum(0, i)
sum(0, j) + a_j <= sum(0, i)

we need a data structure that will allow the following:
*/

int query(int v, int tl, int tr, int k) {
    if (tl == tr) return tl;
    int tm = (tl+tr)/2;
    if (tree[2*v+1] > k && tree[2*v] > k) return -1;
    if (tree[2*v+1] <= k) return query(2*v+1, tm+1, tr, k);
    return query(2*v, tl, tm, k);
}

void update(int v, int tl, int tr, int p, int k) {
    if (tl == tr) tree[v] = k;
    else {
        int tm = (tl+tr)/2;
        if (p <= tm) update(2*v, tl, tm, p, k);
        else update(2*v+1, tm+1, tr, p, k);
        tree[v] = min(tree[2*v], tree[2*v+1]);
    }
}

int getPrfx(int l, int r) {
    int left = (l == 0) ? 0 : prfx[l - 1];
    int right = prfx[r];
    return right - left;
}

bool compare(pi a, pi b) {
    if (a.first > b.first) return true;
    if (a.first < b.first) return false;

    if (a.second < b.second) return true;
    return false;
}


signed main() {
    int n;
    cin >> n;

    tree.resize(4*n, INT64_MAX);
    a.resize(n);
    for (int i = 0; i < n; ++i) cin >> a[i];

    prfx.resize(n);
    prfx[0] = a[0];
    for (int i = 1; i < n; ++i) {
        prfx[i] = prfx[i - 1] + a[i];
    }

    vector<pi> dp(n+1, {INT32_MIN, INT64_MAX});
    dp[0] = {1, 0};
    int mx = 0;

    vi prv;
    for (int i = 0; i < n; i++) {
        int x = a[i];
        pi res = dp[i];
        res.second += x;
        int s1 = getPrfx(0, i);
        
        int pos = query(1, 0, n-1, s1);
        int s2 = getPrfx(pos+1, i);
        pi c;
        if (pos == -1) c = {INT32_MIN, -1};
        else c = {dp[pos+1].first+1, s2};
        if (compare(c, res)) res = c;
        dp[i+1] = res;
        update(1, 0, n-1, i, s1 + res.second);


        /*
        for (int j = 0; j < i; j++) {
            pi c = dp[j+1];
            //cerr << j+1 << ' ' << i << ' ' << getPrfx(j, i-1) << endl;
            int s = getPrfx(j+1, i);

            if (s < c.second) continue;
            c.second = s;
            c.first++;
            if (compare(c, res)) res = c;
        }
        */
        
    }

    cout << dp[n].first;
}
#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...