제출 #143074

#제출 시각아이디문제언어결과실행 시간메모리
143074MilkiBuilding Bridges (CEOI17_building)C++14
100 / 100
217 ms12668 KiB
#include<bits/stdc++.h> using namespace std; #define FOR(i, a, b) for(int i = a; i < b; ++i) #define REP(i, n) FOR(i, 0, n) #define _ << " " << #define sz(x) ((int) x.size()) #define pb(x) push_back(x) #define TRACE(x) cerr << #x << " = " << x << endl #define int long long typedef long long ll; typedef pair<ll, ll> point; typedef long double ld; const int MAXN = 1e5 + 5, MAXV = 105; const ll inf = 1e16; int n, h[MAXN], w[MAXN]; ll dp[MAXN]; ld ccw(point A, point B, point C){ return (ld)A.first * (B.second - C.second) + (ld)B.first * (C.second - A.second) + (ld)C.first * (A.second - B.second); } void merge(vector <point> &lt, vector <point> &rt, vector <point> &hull){ int pnt1 = 0, pnt2 = 0; vector <point> v; while(pnt1 < sz(lt) || pnt2 < sz(rt)){ if(pnt1 == sz(lt)) v.pb(rt[pnt2 ++]); else if(pnt2 == sz(rt)) v.pb(lt[pnt1 ++]); else if(lt[pnt1].first == rt[pnt2].first){ if(lt[pnt1].second < rt[pnt2].second) v.pb(lt[pnt1 ++]); else v.pb(rt[pnt2 ++]); } else if(lt[pnt1].first < rt[pnt2].first) v.pb(lt[pnt1 ++]); else v.pb(rt[pnt2 ++]); } hull.clear(); for(auto it : v){ while(sz(hull) > 1 && ccw( hull[ sz(hull) - 2 ], hull.back(), it) <= 0) hull.pop_back(); hull.pb(it); } } ll check(ll x, point y){ return x * y.first + y.second; } void eval(int x, vector <point> &hull){ if(hull.empty()) return; int lo = 0, hi = sz(hull) - 1; while(lo < hi){ int mid = (lo + hi) >> 1; if(mid + 1 > hi) lo = mid; if( check(h[x], hull[mid]) > check(h[x], hull[mid + 1]) ) lo = mid + 1; else hi = mid; } //TRACE(check(h[x], hull[lo])); //TRACE(hull[lo].first); TRACE(hull[lo].second); dp[x] = min(dp[x], check(h[x], hull[lo]) + w[x - 1] + h[x] * h[x]); } void solve(int lo, int hi, vector <point> &hull){ if(lo > hi) return; if(lo == hi){ hull.pb(point(-2 * h[lo], dp[lo] + h[lo] * h[lo] - w[lo])); return; } vector <point> lt, rt; int mid = (lo + hi) >> 1; FOR(i, lo, hi + 1) eval(i, hull); solve(lo, mid, lt); FOR(i, mid + 1, hi + 1) eval(i, lt); solve(mid + 1, hi, rt); vector <point> tmp; merge(lt, rt, tmp); merge(hull, tmp, hull); } signed main(){ ios_base::sync_with_stdio(false); cin.tie(0); fill(dp, dp + MAXN, inf); dp[1] = 0; cin >> n; REP(i, n) cin >> h[i + 1]; REP(i, n){ cin >> w[i + 1]; if(i > 0) w[i + 1] += w[i]; } /*FOR(i, 2, n + 1){ dp[i] = inf; FOR(j, 1, i){ dp[i] = min(dp[i], dp[j] + (h[i] - h[j]) * (h[i] - h[j]) + w[i - 1] - w[j] ); } }*/ vector <point> v; solve(1, n, v); cout << dp[n]; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...