Submission #1139916

#TimeUsernameProblemLanguageResultExecution timeMemory
1139916minhnguyent546Feast (NOI19_feast)C++20
100 / 100
140 ms7556 KiB
/** * author minhnguyent546 * created_at Sun, 2025-01-26 08:09:26 * problem https://oj.uz/problem/view/NOI19_feast **/ #include <bits/stdc++.h> using namespace std; #ifdef LOCAL #include "cp/debug.h" #else #define debug(...) #define cerr if (false) cerr #endif int n, k; vector<int> arr; vector<long long> pref; void read() { cin >> n >> k; arr.resize(n); for (int i = 0; i < n; ++i) { cin >> arr[i]; } pref.resize(n + 1); for (int i = 0; i < n; ++i) { pref[i + 1] = pref[i] + arr[i]; } } long long sum(int l, int r) { assert(0 <= l && l <= r && r < n); return pref[r + 1] - pref[l]; } const long long INF_LL = 0x3f3f3f3f3f3f3f3f; namespace brute { bool check() { return n <= 300; } void solve() { cerr << " *** [BRUTE] *** " << '\n'; vector<long long> dp(n + 1, -INF_LL); vector<long long> ndp(n + 1); dp[0] = 0; for (int j = 0; j <= k; ++j) { for (int i = 1; i <= n; ++i) { ndp[i] = ndp[i - 1]; if (j > 0) { for (int z = 0; z < i; ++z) { ndp[i] = max(ndp[i], dp[z] + max(0LL, pref[i] - pref[z])); } } } dp.swap(ndp); } cout << dp[n] << '\n'; } } // namespace brute struct Line { int64_t a, b; const static int64_t INF_LL = 0x3f3f3f3f3f3f3f3f; Line(int64_t _a = 0, int64_t _b = INF_LL): a(_a), b(_b) {} int64_t get(int64_t x) { return (int64_t) a * x + b; } pair<int64_t, int64_t > intersect(const Line &other) { return {other.b - b, a - other.a}; } }; struct CHT { int sz; vector<Line> lines; CHT(): sz(0) {} bool can_remove_last(const Line &line) { auto [x1, y1] = lines[sz - 2].intersect(line); auto [x2, y2] = lines[sz - 1].intersect(line); return (__int128_t) x1 * y2 <= (__int128_t) x2 * y1; } void add_line(const Line &new_line) { while (sz >= 2 && can_remove_last(new_line)) { lines.pop_back(); --sz; } lines.emplace_back(new_line); ++sz; } long long get_min(long long x) { int low = 0, high = sz - 1; while (low < high) { int mid = low + (high - low + 1) / 2; if (lines[mid].get(x) > lines[mid + 1].get(x)) { low = mid; } else { high = mid - 1; } } return lines[high].get(x); } }; namespace sub7 { bool check() { return true; } void solve() { cerr << " *** [SUB 7] *** " << '\n'; long long low = -(long long) 1e18, high = 0; vector<long long> dp(n + 1); vector<int> min_seg(n + 1); auto gud = [&](long long lambda) -> bool { fill(dp.begin(), dp.end(), -INF_LL); dp[0] = 0; min_seg[0] = 0; long long max_f = dp[0] - pref[0]; int max_f_min_seg = 0; for (int i = 1; i <= n; ++i) { dp[i] = dp[i - 1]; min_seg[i] = min_seg[i - 1]; long long nval = max_f + pref[i] + lambda; if (nval > dp[i]) { dp[i] = nval; min_seg[i] = max_f_min_seg + 1; } else if (nval == dp[i]) { min_seg[i] = min(min_seg[i], max_f_min_seg + 1); } if (dp[i] - pref[i] > max_f) { max_f = dp[i] - pref[i]; max_f_min_seg = min_seg[i]; } else if (dp[i] - pref[i] == max_f) { max_f_min_seg = min(max_f_min_seg, min_seg[i]); } } return min_seg[n] <= k; }; while (low < high) { long long mid = low + (high - low + 1) / 2; if (gud(mid)) { low = mid; } else { high = mid - 1; } } long long lambda = high; gud(lambda); long long ans = dp[n] - lambda * k; cout << ans << '\n'; } } // namespace sub7 int main() { cin.tie(nullptr)->sync_with_stdio(false); cin.exceptions(cin.failbit); read(); #ifdef LOCAL sub7::solve(); return 0; brute::solve(); return 0; #endif if (brute::check()) { brute::solve(); return 0; } if (sub7::check()) { sub7::solve(); return 0; } assert(false); 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...