Submission #631100

#TimeUsernameProblemLanguageResultExecution timeMemory
631100evenvalueMeetings (IOI18_meetings)C++17
0 / 100
425 ms15192 KiB
#include "meetings.h" #include <bits/stdc++.h> using namespace std; template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>; template<typename T> using max_heap = priority_queue<T, vector<T>, less<T>>; using int64 = long long; using ld = long double; constexpr int kInf = 1e9 + 10; constexpr int64 kInf64 = 1e18 + 10; constexpr int kMod = 1e9 + 7; constexpr int kMaxHeight = 23; template<class node, class F = std::function<node(const node &, const node &)>> class SegTree { int n = 0; std::vector<node> t; F unite; void build(const int x, const int l, const int r, const std::vector<node> &a) { if (l == r) { t[x] = a[l]; return; } const int mid = (l + r) / 2; const int y = 2 * (mid - l + 1) + x; build(x + 1, l, mid, a); build(y, mid + 1, r, a); t[x] = unite(t[x + 1], t[y]); } void update(const int x, const int l, const int r, const int p, const node &v) { if (l == p and p == r) { t[x] = v; return; } const int mid = (l + r) / 2; const int y = 2 * (mid - l + 1) + x; if (p <= mid) { update(x + 1, l, mid, p, v); } else { update(y, mid + 1, r, p, v); } t[x] = unite(t[x + 1], t[y]); } node query(const int x, const int l, const int r, const int ql, const int qr) const { if (ql <= l and r <= qr) { return t[x]; } const int mid = (l + r) / 2; const int y = 2 * (mid - l + 1) + x; if (qr <= mid) { return query(x + 1, l, mid, ql, qr); } else if (mid < ql) { return query(y, mid + 1, r, ql, qr); } else { return unite(query(x + 1, l, mid, ql, qr), query(y, mid + 1, r, ql, qr)); } } void debug_node(const int x, const vector<int> &path) const { for (int i = 0; i < path.size(); i++) { cerr << path[i] << (i == path.size() - 1 ? ": " : " -> "); } cerr << t[x] << '\n'; } void debug(const int x, const int l, const int r, vector<int> path) const { path.push_back(x); if (l == r) { debug_node(x, path); return; } const int mid = (l + r) / 2; const int y = 2 * (mid - l + 1) + x; debug(x + 1, l, mid, path); debug(y, mid + 1, r, path); debug_node(x, path); } public: SegTree() = default; explicit SegTree(const int n, const node e, F f) : n(n), t(2 * n - 1, e), unite(std::move(f)) {} explicit SegTree(const std::vector<node> &a, F f) : n(a.size()), t(2 * (a.size()) - 1), unite(std::move(f)) { build(0, 0, n - 1, a); } void set(const int p, const node &v) { assert(0 <= p and p < n); update(0, 0, n - 1, p, v); } [[nodiscard]] node get(const int l, const int r) const { assert(0 <= l and l <= r and r < n); return query(0, 0, n - 1, l, r); } void debug() const { debug(0, 0, n - 1, {}); cerr << "----------\n\n"; } }; struct node { int peak; vector<int64> left; vector<int64> right; vector<int64> costl; vector<int64> costr; explicit node(const int n, const int peak = kMaxHeight - 1) : peak(peak), left(n), right(n), costl(n, kInf64), costr(n, kInf64) {} }; std::vector<long long> minimum_costs(std::vector<int> H, std::vector<int> L, std::vector<int> R) { const int n = (int) H.size(), q = (int) L.size(); SegTree<node> st(n, node(kMaxHeight), [](const node &l, const node &r) { node ret(kMaxHeight, max(l.peak, r.peak)); //ret.left ret.left = l.left; ret.left[l.peak] += accumulate(r.left.begin(), r.left.begin() + l.peak + 1, 0LL); for (int i = l.peak + 1; i < kMaxHeight; i++) { ret.left[i] += r.left[i]; } //ret.right ret.right = r.right; ret.right[r.peak] += accumulate(l.right.begin(), l.right.begin() + r.peak + 1, 0LL); for (int i = r.peak + 1; i < kMaxHeight; i++) { ret.right[i] += l.right[i]; } //ret.costl int64 sum = 0; int64 sum2 = 0; for (int i = 1; i < kMaxHeight; i++) { sum2 += r.left[i] * i; } for (int hR = 1; hR < kMaxHeight; hR++) { sum += r.left[hR]; sum2 -= r.left[hR] * hR; const int new_hR = max(hR, r.peak); ret.costl[new_hR] = min(ret.costl[new_hR], l.costl[hR] + (sum * hR) + sum2); if (new_hR == ret.peak) { ret.costr[ret.peak] = min(ret.costr[ret.peak], l.costl[hR] + (sum * hR) + sum2); } } //ret.costr sum = 0; sum2 = 0; for (int i = 1; i < kMaxHeight; i++) { sum2 += l.right[i] * i; } for (int hL = 1; hL < kMaxHeight; hL++) { sum += l.right[hL]; sum2 -= l.right[hL] * hL; const int new_hL = max(hL, l.peak); ret.costr[new_hL] = min(ret.costr[new_hL], r.costr[hL] + (sum * hL) + sum2); if (new_hL == ret.peak) { ret.costl[ret.peak] = min(ret.costl[ret.peak], r.costr[hL] + (sum * hL) + sum2); } } return ret; }); for (int i = 0; i < n; i++) { node x(kMaxHeight, H[i]); x.left[H[i]] = 1; x.right[H[i]] = 1; fill(x.costl.begin(), x.costl.end(), H[i]); fill(x.costr.begin(), x.costr.end(), H[i]); st.set(i, x); } vector<int64> ans(q); for (int i = 0; i < q; i++) { const node x = st.get(L[i], R[i]); ans[i] = min(*min_element(x.costl.begin(), x.costl.end()), *min_element(x.costr.begin(), x.costr.end())); } 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...