Submission #1095235

#TimeUsernameProblemLanguageResultExecution timeMemory
1095235LonlyRSplit the sequence (APIO14_sequence)C++17
100 / 100
750 ms96564 KiB
#include<bits/stdc++.h> #define int long long #define ld long double #define sz(u) (int)u.size() using namespace std; const int maxn = 1e5 + 5; int n, k; int a[maxn], dp[2][205], pf[maxn]; signed pre[maxn][205]; struct iii{ int a, b; ld x; int p; }; inline ld ori(iii a, iii b) { int u = a.a, v = a.b; int x = b.a, y = b.b; if (u == x) return (ld)1e18; return (ld)(y - v) / (ld)(u - x); } void trace(int n, int k) { if (pre[n][k] == 0) return; trace(pre[n][k], k - 1); assert(pre[n][k] != n); cout << pre[n][k] << " "; } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); // freopen("test.inp", "r", stdin); // freopen("test.out", "w", stdout); cin >> n >> k; assert(k > 0); for (int i = 1; i <= n; i++) cin >> a[i], pf[i] = pf[i - 1] + a[i]; /// dp[i][j] = dp[k - 1][j - 1] + (pf[i] - pf[k - 1]) * (pf[n] - pf[i]) /// dp[i][j] = pf[k - 1] * pf[i] + dp[k - 1][j - 1] + pf[n] * pf[i] - pf[i] ^ 2 - pf[k - 1] * pf[n] vector<iii> b[2]; int be = 0, cu = 1; b[0].push_back({0, 0, -1e18, 0}); k++; for (int j = 0; j < k; j++) { b[cu].clear(); for (int i = 1 + j, pt = -1; i <= n; i++) { pt = min(pt, sz(b[be]) - 2); dp[cu][j + 1] = -1e18; while (pt + 1 < sz(b[be]) && (ld)pf[i] >= b[be][pt + 1].x) { pt++; int val = b[be][pt].a * pf[i] + b[be][pt].b - pf[i] * pf[i] + pf[n] * pf[i]; if (b[be][pt].p != i && dp[cu][j + 1] < val) dp[cu][j + 1] = val, pre[i][j + 1] = b[be][pt].p; } int val = b[be][pt].a * pf[i] + b[be][pt].b - pf[i] * pf[i] + pf[n] * pf[i]; if (b[be][pt].p != i && dp[cu][j + 1] < val) dp[cu][j + 1] = val, pre[i][j + 1] = b[be][pt].p; if (pt > 0) { int val = b[be][pt - 1].a * pf[i] + b[be][pt - 1].b - pf[i] * pf[i] + pf[n] * pf[i]; if (b[be][pt - 1].p != i && dp[cu][j + 1] < val) dp[cu][j + 1] = val, pre[i][j + 1] = b[be][pt - 1].p; } iii now; now.a = pf[i]; now.b = dp[cu][j + 1] - pf[i] * pf[n]; now.p = i; now.x = -1e18; while (sz(b[cu]) >= 2 && ori(b[cu][sz(b[cu]) - 2], now) <= ori(b[cu][sz(b[cu]) - 2], b[cu][sz(b[cu]) - 1])) b[cu].pop_back(); if (b[cu].size()) now.x = ori(now, b[cu].back()); b[cu].emplace_back(now); } swap(cu, be); } cout << dp[be][k] << "\n"; trace(n, k); }
#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...