제출 #1122242

#제출 시각아이디문제언어결과실행 시간메모리
1122242_callmelucianBuilding Bridges (CEOI17_building)C++14
100 / 100
53 ms10520 KiB
// Massive thanks to Monarchuwu and VNOI for // the wonderful blog about line-container (coming soon) #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef pair<ll,ll> pl; typedef pair<int,int> pii; typedef tuple<int,int,int> tpl; #define all(a) a.begin(), a.end() #define filter(a) a.erase(unique(all(a)), a.end()) const ld oo = 1e7; struct line { ll slope, c; mutable ld p; line() : slope(0), c(0), p(-oo) {} line (ll u, ll v) : slope(u), c(v), p(-oo) {} ll calc (ll x) const { return slope * x + c; } bool operator < (const line &o) const { return (slope == o.slope ? c < o.c : slope > o.slope); } bool operator < (ll x) const { return p < x; } }; struct lineContainer : multiset<line, less<void>> { // use less<void> to allow multiple comparator ld xSect (auto x, auto y) { if (x->slope == y->slope) { while (true); } return (ld) (y->c - x->c) / (x->slope - y->slope); } bool mustKeep (auto x, auto y) { // return true if we must keep y and update x->p accordingly // note that x->p at the beginning of the function is not correct if (y == end()) return x->p = oo, 1; if (x->slope == y->slope) return 0; // edge case: parallel return ((x->p = xSect(x, y)) < y-> p); } void add (ll slope, ll c) { // remove lines after x auto x = emplace(slope, c), y = next(x); while (!mustKeep(x, y)) y = erase(y); // perhaps remove x if (x != begin()) { y = prev(x); if (!mustKeep(y, x)) mustKeep(y, erase(x)); // must re-calculate because y->p is y & x after `if` clause } else return; // remove lines before x while (y != begin()) { x = prev(y); if (x->p >= y->p) mustKeep(x, erase(y)), y = x; else break; } } ll query (ll x) { return lower_bound(x)->calc(x); } }; int main() { ios::sync_with_stdio(0); cin.tie(0); int n; cin >> n; vector<ll> h(n + 1), w(n + 1); for (int i = 1; i <= n; i++) cin >> h[i]; for (int i = 1; i <= n; i++) { cin >> w[i]; w[i] += w[i - 1]; } lineContainer hull; hull.add(-2 * h[1], h[1] * h[1] - w[1]); for (int i = 2; i <= n; i++) { ll dp = hull.query(h[i]) + h[i] * h[i] + w[i - 1]; if (i == n) return cout << dp, 0; hull.add(-2 * h[i], h[i] * h[i] - w[i] + dp); } return 0; }

컴파일 시 표준 에러 (stderr) 메시지

building.cpp:35:15: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
   35 |     ld xSect (auto x, auto y) {
      |               ^~~~
building.cpp:35:23: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
   35 |     ld xSect (auto x, auto y) {
      |                       ^~~~
building.cpp:42:20: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
   42 |     bool mustKeep (auto x, auto y) {
      |                    ^~~~
building.cpp:42:28: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
   42 |     bool mustKeep (auto x, auto y) {
      |                            ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...