Submission #753932

#TimeUsernameProblemLanguageResultExecution timeMemory
753932JohannBuilding Bridges (CEOI17_building)C++14
100 / 100
75 ms11372 KiB
#include "bits/stdc++.h" using namespace std; #pragma GCC optimize("O3") #pragma GCC target("avx,avx2,tune=native") typedef long long ll; typedef vector<ll> vi; typedef vector<vi> vvi; #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() const ll INF = 1LL << 60; int N; vi H; vi W; ll ans; vi dp; struct segment { mutable ll l, r; ll m, a; int type = 0; // 0 - normal, 1 - compare by l, 2 - compare by m bool operator<(const segment &o) const { if (type == 1 || o.type == 1) return l < o.l; if (type == 2 || o.type == 2) return m > o.m; return l < o.l; } }; double intersection(ll m1, ll a1, ll m2, ll a2) { return (a1 - a2) / (double)(m2 - m1); // todo parallel??? } struct convexHull { set<segment> H; void insert(ll m, ll a) { auto it1 = H.lower_bound({0, 0, m, 0, 2}); if (it1 != H.end() && it1->m == m) { if (it1->a <= a) return; it1 = H.erase(it1); } if (it1 == H.begin()) it1 = H.end(); else { --it1; // the elements with o.m > m while (intersection(it1->m, it1->a, m, a) < it1->r) { double inter = intersection(it1->m, it1->a, m, a); if (inter < it1->l) it1 = --H.erase(it1); else it1->r = (ll)floor(inter); } } auto it2 = H.upper_bound({0, 0, m, 0, 2}); while (it2 != H.end() && intersection(it2->m, it2->a, m, a) > it2->l) { double inter = intersection(it2->m, it2->a, m, a); if (inter > it2->r) it2 = H.erase(it2); else it2->l = (ll)ceil(inter); } if (it1 == H.end() || it2 == H.end() || it1->r + 1 < it2->l) { H.insert({(it1 == H.end()) ? -INF : it1->r + 1, (it2 == H.end()) ? INF : it2->l - 1, m, a, 0}); } } ll query(ll x) { segment seg = *(--H.upper_bound({x, 0, 0, 0, 1})); return seg.m * x + seg.a; } }; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> N; H.resize(N), W.resize(N), dp.resize(N); for (int i = 0; i < N; ++i) cin >> H[i]; for (int i = 0; i < N; ++i) cin >> W[i]; ans = accumulate(all(W), 0LL); convexHull hull; dp[0] = -W[0]; hull.insert(-2 * H[0], dp[0] + H[0] * H[0]); // first pillar for (int i = 1; i < N; ++i) { dp[i] = hull.query(H[i]) - W[i] + H[i] * H[i]; hull.insert(-2 * H[i], dp[i] + H[i] * H[i]); } cout << dp.back() + ans << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...