제출 #608209

#제출 시각아이디문제언어결과실행 시간메모리
608209piOOEMeetings (IOI18_meetings)C++17
60 / 100
5542 ms56892 KiB
#include <bits/stdc++.h> #include "meetings.h" using namespace std; using ll = long long; const ll inf = 3e18; vector<ll> smart20(vector<int> a, vector<int> L, vector<int> R) { int n = (int) a.size(); int q = (int) L.size(); vector<ll> ans(q, inf); int logn = __lg(n) + 1; vector<vector<int>> st(logn); vector<vector<ll>> sp(logn); st[0] = a; for (int i = 1; i < logn; ++i) { st[i].resize(n - (1 << i) + 1); for (int j = 0; j <= (n - (1 << i)); ++j) { st[i][j] = max(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]); } } auto get = [&](int l, int r) { if (!(r > l && l >= 0 && r <= n)) { assert(false); } int lg = __lg(r - l); return max(st[lg][l], st[lg][r - (1 << lg)]); }; int mx = *max_element(a.begin(), a.end()); vector<int> g[mx + 1]; vector pref(mx + 1, vector<ll>(n)), suf(mx + 1, vector<ll>(n)); for (int i = 0; i < n; ++i) { g[a[i]].push_back(i); } for (int i = 0; i < n; ++i) { auto FirstBigger = [&](int x) { int l = -1, r = i; while (l + 1 < r) { int mid = (l + r) >> 1; if (get(mid, i + 1) > x) { l = mid; } else { r = mid; } } return l; }; int j = FirstBigger(a[i]); ll val = a[i] * (i - j) + (j == -1 ? 0 : pref[0][j]); for (int x = 0; x <= a[i]; ++x) { pref[x][i] = val; } for (int x = a[i] + 1; x <= mx; ++x) { j = FirstBigger(x); pref[x][i] = x * (i - j) + (j == -1 ? 0 : pref[0][j]); } } for (int i = n - 1; i > -1; --i) { auto FirstBigger = [&](int x) { int l = i, r = n + 1; while (l + 1 < r) { int mid = (l + r) >> 1; if (get(i, mid) > x) { r = mid; } else { l = mid; } } return l; }; int j = FirstBigger(a[i]); ll val = a[i] * (j - i) + (j == n ? 0 : suf[0][j]); for (int x = 0; x <= a[i]; ++x) { suf[x][i] = val; } for (int x = a[i] + 1; x <= mx; ++x) { j = FirstBigger(x); suf[x][i] = x * (j - i) + (j == n ? 0 : suf[0][j]); } } sp[0].resize(n); for (int i = 0; i < n; ++i) { sp[0][i] = pref[a[i]][i] + suf[a[i]][i] - a[i]; } for (int i = 1; i < logn; ++i) { sp[i].resize(n - (1 << i) + 1); for (int j = 0; j <= (n - (1 << i)); ++j) { sp[i][j] = min(sp[i - 1][j], sp[i - 1][j + (1 << (i - 1))]); } } for (int t = 0; t < q; ++t) { int l = L[t], r = R[t]; vector<int> nxt; for (int x = 1; x <= mx; ++x) { auto it = lower_bound(g[x].begin(), g[x].end(), l); if (it != g[x].end() && *it <= r) { nxt.push_back(*it); it = upper_bound(g[x].begin(), g[x].end(), r); nxt.push_back(*prev(it)); } } sort(nxt.begin(), nxt.end()); nxt.resize(unique(nxt.begin(), nxt.end()) - nxt.begin()); int m = (int) nxt.size(); auto get_min = [&](int l, int r) { if (!(r > l && l >= 0 && r <= n)) { return inf; } int lg = __lg(r - l); return min(sp[lg][l], sp[lg][r - (1 << lg)]); }; for (int id = 0; id < m; ++id) { int i = nxt[id]; int right = id == m - 1 ? r + 1 : nxt[id + 1]; { ans[t] = min(ans[t], (pref[a[i]][i] + suf[a[i]][i] - a[i]) - (l == 0 ? 0 : pref[get(l, i + 1)][l - 1]) - (r == n - 1 ? 0 : suf[get(i, r + 1)][r + 1])); } if (right <= r) { ans[t] = min(ans[t], get_min(i + 1, right) - (l == 0 ? 0 : pref[get(l, i + 1)][l - 1]) - (r == n - 1 ? 0 : suf[get(i + 1, r + 1)][r + 1])); } } } return ans; } vector<ll> stupid(vector<int> a, vector<int> L, vector<int> R) { int n = (int) a.size(); int q = (int) L.size(); vector<ll> ans(q, inf); vector<ll> pref(n), suf(n); for (int t = 0; t < q; ++t) { int l = L[t], r = R[t]; vector<int> stk; ll sum = 0; for (int i = l; i <= r; ++i) { while (!stk.empty() && a[stk.back()] <= a[i]) { int j = stk.back(); stk.pop_back(); sum += (a[i] - a[j]) * (ll) (j - (stk.empty() ? l - 1 : stk.back())); } stk.push_back(i); sum += a[i]; pref[i] = sum; } stk.clear(); sum = 0; for (int i = r; i >= l; --i) { while (!stk.empty() && a[stk.back()] <= a[i]) { int j = stk.back(); stk.pop_back(); sum += (a[i] - a[j]) * (ll) ((stk.empty() ? r + 1 : stk.back()) - j); } stk.push_back(i); sum += a[i]; suf[i] = sum; } ans[t] = inf; for (int i = l; i <= r; ++i) { ans[t] = min(ans[t], pref[i] + suf[i] - a[i]); } } return ans; } vector<ll> minimum_costs(vector<int> a, vector<int> L, vector<int> R) { if (*max_element(a.begin(), a.end()) <= 20) { return smart20(a, L, R); } else { return stupid(a, L, R); } }
#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...