Submission #767899

#TimeUsernameProblemLanguageResultExecution timeMemory
767899Andrei_CalotaBuilding Bridges (CEOI17_building)C++14
100 / 100
92 ms17944 KiB
#include <bits/stdc++.h> using namespace std; using int64 = long long; const int N_MAX = 1e5; const int VALUE_MAX = 1e6; int64 h[1 + N_MAX], w[1 + N_MAX]; int n; int64 pSum[1 + N_MAX]; void initInput (void) { cin >> n; for (int i = 1; i <= n; i ++) cin >> h[i]; for (int i = 1; i <= n; i ++) cin >> w[i]; for (int i = 1; i <= n; i ++) pSum[i] = pSum[i - 1] + w[i]; } struct defLine { int64 slope, h; int64 getEval (int64 t) {return slope * t + h;} }; const int64 myINF = 1e18; struct LiChaoNode { defLine line; LiChaoNode* u; LiChaoNode* v; LiChaoNode () { line = {0, +myINF}; u = NULL; v = NULL; } }; void update (LiChaoNode* root, int left, int right, defLine newLine) { if (left == right) { if (root -> line.getEval (left) > newLine.getEval (left)) swap (root -> line, newLine); } else { int mid = left + (right - left) / 2; if (root -> line.getEval (mid) > newLine.getEval (mid)) swap (root -> line, newLine); if (root -> line.slope < newLine.slope) { if (root -> u == NULL) root -> u = new LiChaoNode; update (root -> u, left, mid, newLine); } else { if (root -> v == NULL) root -> v = new LiChaoNode; update (root -> v, mid + 1, right, newLine); } } } int64 query (LiChaoNode* root, int left, int right, int64 t) { if (left == right) return root -> line.getEval (t); int mid = left + (right - left) / 2; int64 answer = root -> line.getEval (t); if (t <= mid && root -> u != NULL) answer = min (answer, query (root -> u, left, mid, t)); else if (root -> v != NULL) answer = min (answer, query (root -> v, mid + 1, right, t)); return answer; } int64 DP[1 + N_MAX]; void solve (void) { LiChaoNode* CHT = new LiChaoNode; DP[1] = 0; update (CHT, 0, VALUE_MAX, {-2 * h[1], DP[1] + h[1] * h[1] - w[1]}); for (int i = 2; i <= n; i ++) { DP[i] = h[i] * h[i] + pSum[i - 1] + query (CHT, 0, VALUE_MAX, h[i]); defLine newLine = {-2 * h[i], DP[i] + h[i] * h[i] - pSum[i]}; update (CHT, 0, VALUE_MAX, newLine); ///cout << DP[i] << "\n"; } cout << DP[n]; } int main() { initInput (); solve (); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...