(UPD: 2024-12-04 14:48 UTC) Judge is not working due to Cloudflare incident. (URL) We can do nothing about it, sorry. After the incident is resolved, we will grade all submissions.

Submission #78672

#TimeUsernameProblemLanguageResultExecution timeMemory
78672imeimi2000Meetings (IOI18_meetings)C++17
100 / 100
5392 ms204364 KiB
#include "meetings.h" #include <algorithm> #include <functional> using namespace std; typedef long long llong; typedef pair<int, int> pii; int n; const llong inf = 1e18; vector<llong> ans; pii mx[1 << 21]; struct query { int i, l, r; query(int i, int l, int r) : i(i), l(l), r(r) {} }; struct line { llong m, b; llong get(int x) const { return m * x + b; } line() {} line(llong m, llong b) : m(m), b(b) {} }; struct node { llong lz; line l; llong get(int x) const { return l.get(x); } } seg[1 << 21]; vector<query> qs[750001]; pii arr[750001]; void init(int i, int s, int e) { seg[i].l = line(0, inf); seg[i].lz = 0; if (s == e) { mx[i] = arr[s]; return; } int m = (s + e) / 2; init(i << 1, s, m); init(i << 1 | 1, m + 1, e); mx[i] = max(mx[i << 1], mx[i << 1 | 1]); } pii getMax(int i, int s, int e, int x, int y) { if (e < x || y < s) return pii(0, 0); if (x <= s && e <= y) return mx[i]; int m = (s + e) / 2; return max(getMax(i << 1, s, m, x, y), getMax(i << 1 | 1, m + 1, e, x, y)); } void update(int i, int s, int e, int x, int y, line l) { if (e < x || y < s) return; l.b -= seg[i].lz; int m = (s + e) / 2; if (x <= s && e <= y) { bool A = seg[i].l.get(s) < l.get(s); bool B = seg[i].l.get(m) < l.get(m); if (!B) swap(seg[i].l, l); if (s == e) return; if (A != B) update(i << 1, s, m, x, y, l); else update(i << 1 | 1, m + 1, e, x, y, l); return; } update(i << 1, s, m, x, y, l); update(i << 1 | 1, m + 1, e, x, y, l); } void add(int i, int s, int e, int x, int y, llong v) { if (e < x || y < s) return; if (x <= s && e <= y) { seg[i].lz += v; return; } int m = (s + e) / 2; add(i << 1, s, m, x, y, v); add(i << 1 | 1, m + 1, e, x, y, v); } llong get(int i, int s, int e, int x) { llong ret = seg[i].get(x); if (s == e) return ret + seg[i].lz; int m = (s + e) / 2; if (x <= m) return min(ret, get(i << 1, s, m, x)) + seg[i].lz; return min(ret, get(i << 1 | 1, m + 1, e, x)) + seg[i].lz; } void getQuery(int s, int e) { if (s > e) return; int m = abs(getMax(1, 1, n, s, e).second); getQuery(s, m - 1); getQuery(m + 1, e); for (query q : qs[m]) { llong R = m < q.r ? get(1, 1, n, q.r) : 0; ans[q.i] = min(ans[q.i], R + (m - q.l + 1ll) * arr[m].first); } add(1, 1, n, m, e, (m - s + 1ll) * arr[m].first); llong Lm = s < m ? get(1, 1, n, m - 1) : 0; line l(arr[m].first, Lm + (1ll - m) * arr[m].first); update(1, 1, n, m, e, l); } vector<llong> minimum_costs(vector<int> H, vector<int> L, vector<int> R) { n = H.size(); int q = L.size(); ans.resize(q, inf); for (int i = 0; i < n; ++i) arr[i + 1] = pii(H[i], i + 1); init(1, 1, n); for (int i = 0; i < q; ++i) { int mx = getMax(1, 1, n, L[i] + 1, R[i] + 1).second; qs[mx].emplace_back(i, L[i] + 1, R[i] + 1); } getQuery(1, n); for (int i = 1; i <= n; ++i) qs[i].clear(); for (int i = 0; i < n; ++i) arr[n - i] = pii(H[i], i - n); init(1, 1, n); for (int i = 0; i < q; ++i) { int mx = -getMax(1, 1, n, n - R[i], n - L[i]).second; qs[mx].emplace_back(i, n - R[i], n - L[i]); } getQuery(1, n); return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...