Submission #1012693

#TimeUsernameProblemLanguageResultExecution timeMemory
1012693andrei_iorgulescuSplit the sequence (APIO14_sequence)C++17
33 / 100
270 ms131072 KiB
#include <bits/stdc++.h> using namespace std; #define int long long int inf = 5e18; int n,k,a[100005]; int dp[205][100005]; int f[100005]; int ant[205][100005]; struct dreapta { int offset, panta; int eval(int x) { return offset + panta * x; } }; deque<pair<dreapta,int>> dq; void update(dreapta d,int pos) { dq.push_back({d,pos}); while (dq.size() >= 2) { dreapta d1 = dq.back().first; int pos1 = dq.back().second; dq.pop_back(); dreapta d2 = dq.back().first; int pos2 = dq.back().second; if (d1.panta != d2.panta) { dq.push_back({d1,pos1}); break; } else { dq.pop_back(); if (d1.offset > d2.offset) dq.push_back({d1,pos1}); else dq.push_back({d2,pos2}); } } } int query(int x) { if (dq.empty()) return -inf; while (dq.size() >= 2) { dreapta d1 = dq.front().first; int pos1 = dq.front().second; dq.pop_front(); dreapta d2 = dq.front().first; if (d1.eval(x) > d2.eval(x)) { dq.push_front({d1,pos1}); break; } } return dq.front().first.eval(x); } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> n >> k; for (int i = 1; i <= n; i++) cin >> a[i]; f[n] = a[n]; for (int i = n - 1; i >= 1; i--) f[i] = f[i + 1] + a[i]; dp[0][1] = 0; for (int i = 2; i <= n; i++) dp[0][i] = -inf; for (int j = 1; j <= k; j++) { dq.clear(); for (int i = 1; i <= n; i++) { dp[j][i] = query(f[i]) - f[i] * f[i]; if (!dq.empty()) ant[j][i] = dq.front().second; dreapta aux; aux.offset = dp[j - 1][i]; aux.panta = f[i]; update(aux,i); } } int ans = 0; for (int i = k + 1; i <= n; i++) ans = max(ans,dp[k][i]); cout << ans << '\n'; int cine; for (int i = k + 1; i <= n; i++) if (dp[k][i] == ans) cine = i; vector<int> lol; for (int i = k; i >= 1; i--) { lol.push_back(cine - 1); cine = ant[i][cine]; } reverse(lol.begin(),lol.end()); for (auto it : lol) cout << it << ' '; return 0; } /* 7 3 4 1 3 4 0 2 3 */ /** Nu conteaza ordinea operatiilor, so dp[j][i] = facand j splituri pe locuri pana inainte de i (ultimul pe i), care e suma maxima pe care o pot obtine dp[j][i] = max(dp[j - 1][q < i] + f[i] * (f[q] - f[i])) f[i] = suma pe sufix de la i incolo deci am -f[i] * f[i] mereu, vreau maximul din dp[j - 1][q < i] + f[i] * f[q] Asta e evident CHT, cu update: dreapta dp[j - 1][i] cu panta f[i] si query in f[i] Query-urile sunt sortate descrescator si update-urile sunt tot descrescator dupa panta **/

Compilation message (stderr)

sequence.cpp: In function 'int main()':
sequence.cpp:110:28: warning: 'cine' may be used uninitialized in this function [-Wmaybe-uninitialized]
  110 |         lol.push_back(cine - 1);
      |                       ~~~~~^~~
#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...