Submission #1336311

#TimeUsernameProblemLanguageResultExecution timeMemory
1336311aaaaaaaaBigger segments (IZhO19_segments)C++20
37 / 100
1595 ms6696 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int inf = 2e18;


struct segment_tree{
    int N;
    vector<int> seg;
    segment_tree(int n){
        seg.resize(n * 4, inf);
        N = n;
    }
    void update(int node, int start, int end, int idx, int val){
        if(start == end){
            seg[node] = val;
            return;
        }
        int mid = start + (end - start) / 2;
        if(idx <= mid) update(node * 2 + 1, start, mid, idx, val);
        else update(node * 2 + 2, mid + 1, end, idx, val);
        seg[node] = min(seg[node * 2 + 1], seg[node * 2 + 2]);
    }
    int query(int node, int start, int end, int val){
        if(seg[node] > val) return -1;
        if(start == end) return start;
        int mid = start + (end - start) / 2;
        if(seg[node * 2 + 2] <= val) return query(node * 2 + 2, mid + 1, end, val);
        else if(seg[node * 2 + 1] <= val) return query(node * 2 + 1, start, mid, val);
        return -1;
    }
    int query(int val){
        return query(0, 1, N, val);
    }
    void update(int idx, int val){
        update(0, 1, N, idx, val);
    }
};


signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr); cout.tie(nullptr);

    int n, ans = 1;
    cin >> n;

    vector<int> a(n + 1, 0), pref(n + 5, 0);

    for(int i = 1; i <= n; ++i){
        cin >> a[i];
        pref[i] = pref[i - 1] + a[i];
    }

    vector<int> pdp(n + 1, inf);
    pdp[0] = 0;

    for(int i = 1; i <= n; ++i){
        pdp[i] = pdp[i - 1] + a[i];
    }

    segment_tree tr(n);

    pdp[0] = inf;

    for(int i = 1; i <= n; ++i){
        tr.update(i, pdp[i - 1] + pref[i - 1]);
    }


    for(int k = 2; k <= n; ++k){
        vector<int> ndp(n + 2, inf);
        for(int i = k; i <= n; ++i){
            /*
                ndp[i] = maximum j such that pref[i] - pref[j - 1] >= pdp[j - 1]
            */

            int query = tr.query(pref[i]);

            if(query > 0){
                ndp[i] = pref[i] - pref[query - 1];
            }

           // cout << "splitting at : " << i << " with parts: " << k << " last value: " << ndp[i] << " last: " << query << "\n";

            if(ndp[i] < inf) ans = max(ans, k);
        }

    for(int i = 1; i <= n; ++i){
        tr.update(i, ndp[i - 1] + pref[i - 1]);
    }

    }

    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...