제출 #652996

#제출 시각아이디문제언어결과실행 시간메모리
652996vladutpieleBigger segments (IZhO19_segments)C++17
0 / 100
0 ms212 KiB
#include <bits/stdc++.h> #define int long long using namespace std; const int nmax = 500000; int n; int v[nmax + 5], sume[nmax + 5]; struct elem { int maxSeg; /// in cate segmente impart prefixul [1 ... i] int minSum; /// suma minima pentru ultimul segment int maxPrv; /// cel mai mare capat dreapta al segmentului dp[i].maxSeg - 1 ///daca capatul stanga al ultimului segment e j, maxPrv este j - 1 }; elem dp[nmax + 5]; signed main() { cin >> n; for(int i = 1; i <= n; i ++) { cin >> v[i]; sume[i] = sume[i - 1] + v[i]; } /// initializare for(int i = 1; i <= n; i ++) { dp[i] = {1, sume[i], 0}; } /// cum pot sa calculez cel mai usor dp[i].maxPrv? /// segmentul [a .... b] este un segment care imbunatateste solutia /// daca sume[b] - sume[a - 1] >= sume[a - 1] - sume[dp[a].maxPrv] /// relatie echivalenta cu : sume[b] >= 2 * sume[a - 1] - sume[dp[a - 1].maxPrv] /// astfel pot sa caut binar valoarea a (cel mai mare a) for(int i = 2; i <= n; i ++) { if(dp[i - 1].maxSeg > dp[i].maxSeg) { dp[i].maxSeg = dp[i - 1].maxSeg; dp[i].minSum = sume[i] - sume[dp[i - 1].maxPrv]; dp[i].maxPrv = dp[i - 1].maxPrv; } else { if(dp[i - 1].maxSeg == dp[i].maxSeg) { if(sume[i] - sume[dp[i - 1].maxPrv] < dp[i].minSum) { dp[i].minSum = sume[i] - sume[dp[i - 1].maxPrv]; dp[i].maxPrv = dp[i - 1].maxPrv; } } } dp[i].maxSeg = dp[i - 1].maxSeg; dp[i].minSum = dp[i - 1].minSum + v[i]; dp[i].maxPrv = dp[i - 1].maxPrv; int st = 1, dr = i - 2; int maxPrv = 0; while(st <= dr) { int mid = (st + dr) >> 1; if(sume[i] >= 2 * sume[mid] - sume[dp[mid].maxPrv]) { maxPrv = mid; st = mid + 1; } else { dr = mid - 1; } } if(maxPrv == 0) { continue; } if(1 + dp[maxPrv].maxSeg > dp[i].maxSeg) { dp[i].maxSeg = 1 + dp[maxPrv].maxSeg; dp[i].minSum = sume[i] - sume[maxPrv]; dp[i].maxPrv = maxPrv; } else { if(1 + dp[maxPrv].maxSeg == dp[i].maxSeg) { if(sume[i] - sume[maxPrv] < dp[i].minSum) { dp[i].minSum = sume[i] - sume[maxPrv]; dp[i].maxPrv = maxPrv; } } } } cout << dp[n].maxSeg << '\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...