Submission #1177165

#TimeUsernameProblemLanguageResultExecution timeMemory
1177165vicvicBuilding Bridges (CEOI17_building)C++20
60 / 100
125 ms22904 KiB
#include <iostream> #include <fstream> #include <set> #include <vector> #include <map> #include <limits> using namespace std; const long double inf=numeric_limits <long double>::infinity(); const long double MAX_SLOPE=1e6+5; const int NMAX=1e5; struct line { long double slope, intercept; line (long double _slope, long double _intercept) { slope=_slope; intercept=_intercept; } long long operator () (long long x) { return slope*x+intercept; } }; line ultra_slopper (MAX_SLOPE, 0); bool operator < (line a, line b) { if (a.slope==b.slope) return a.intercept<b.intercept; return a.slope<b.slope; } long double meet (line a, line b) { return (long double) (a.intercept-b.intercept)/ (long double) (b.slope-a.slope); } class ConvexHull { public: set <pair <long double, line>> prevX; map <line, pair <long double, long double>> limits; ConvexHull (line a) { limits[a]={-inf, inf}; prevX.insert ({-inf, a}); } void insert (line function) { if (limits.count (function)) return; auto poz=limits.insert ({function, {0, 0}}).first; if (poz!=limits.begin() && prev (poz) -> first.slope==function.slope) { limits.erase (poz); return; } if (next (poz)!=limits.end() && next (poz) -> first.slope==function.slope) { prevX.erase ({next (poz) -> second.first, next(poz) -> first}); limits.erase (next (poz)); } if (poz!=limits.begin() && next (poz)!=limits.end() && meet (next (poz) -> first, function)>=next (poz) -> second.second && meet (prev (poz) -> first, function)<=prev (poz) -> second.first) { limits.erase (poz); return; } while (next(poz)!=limits.end()) { if (meet (next (poz) -> first, function)<=next (poz) -> second.first) { prevX.erase ({next (poz) -> second.first, next (poz) -> first}); limits.erase (next (poz)); } else { next (poz) -> second.second=meet (next (poz) -> first, function); poz -> second.first=meet (next (poz) -> first, function); break; } } if (next (poz)==limits.end()) { poz -> second.first=-inf; } while (poz!=limits.begin()) { if (meet (prev (poz) -> first, function)>=prev (poz) -> second.second) { prevX.erase ({prev (poz) -> second.first, prev (poz) -> first}); limits.erase (prev (poz)); } else { prevX.erase ({prev (poz) -> second.first, prev (poz) -> first}); prev (poz) -> second.first=meet (prev (poz) -> first, function); prevX.insert ({prev (poz) -> second.first, prev (poz) -> first}); poz -> second.second=meet (prev (poz) -> first, function); break; } } if (poz==limits.begin()) { poz -> second.second=inf; } prevX.insert ({poz -> second.first, function}); } long long query (long long x) { line seg=prev (prevX.upper_bound ({x, ultra_slopper})) -> second; return seg (x); } }; long long int n, h[NMAX+5], dp[NMAX+5], v[NMAX+5]; int main () { cin >> n; for (int i=1;i<=n;i++) { cin >> h[i]; } for (int i=1;i<=n;i++) { cin >> v[i]; } int sum=v[1]; ConvexHull cht (line (h[1], -sum+h[1]*h[1]+dp[1])); for (int i=2;i<=n;i++) { dp[i]=sum+h[i]*h[i]+cht.query (-2*h[i]); sum+=v[i]; cht.insert (line (h[i], -sum+h[i]*h[i]+dp[i])); } cout << dp[n]; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...