(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 #795107

#TimeUsernameProblemLanguageResultExecution timeMemory
795107ymmMeetings (IOI18_meetings)C++17
100 / 100
2441 ms479456 KiB
#include "meetings.h" #include <bits/stdc++.h> #define Loop(x,l,r) for (ll x = (l); x < (ll)(r); ++x) #define LoopR(x,l,r) for (ll x = (r)-1; x >= (ll)(l); --x) typedef long long ll; typedef std::pair<int, int> pii; typedef std::pair<ll , ll > pll; using namespace std; const int N = 1e6+10; ll eval(const pll &f, ll x) { return f.first * x + f.second; } namespace seg { struct node { pll val; ll lzy; ll fst, lst; bool leaf; } t[N*4]; int sz; void init(int n) { sz = n; t[0].val = {}; t[0].lzy = 0; t[0].fst = 0; t[0].lst = 0; t[0].leaf = 1; } void up(int i, ll x) { t[i].val.second += x; t[i].lzy += x; t[i].fst += x; t[i].lst += x; } void ppg(int i, int b, int e) { if (t[i].leaf) { t[2*i+1] = t[2*i+2] = t[i]; t[2*i+1].lst = eval(t[2*i+1].val, (b+e)/2-1); t[2*i+2].fst = eval(t[2*i+2].val, (b+e)/2); t[i].leaf = 0; } else { up(2*i+1, t[i].lzy); up(2*i+2, t[i].lzy); } t[i].lzy = 0; } void merge(int i) { t[i].fst = t[2*i+1].fst; t[i].lst = t[2*i+2].lst; } void add(int l, int r, ll x, int i, int b, int e) { if (l <= b && e <= r) { up(i, x); return; } ppg(i, b, e); if (l < (b+e)/2) add(l, r, x, 2*i+1, b, (b+e)/2); if ((b+e)/2 < r) add(l, r, x, 2*i+2, (b+e)/2, e); merge(i); } void add(int l, int r, ll x) { add(l, r, x, 0, 0, sz); } void mn(int l, int r, pll f, int i, int b, int e) { ll fst2 = eval(f, b); ll lst2 = eval(f, e-1); if (l <= b && e <= r && t[i].fst >= fst2 && t[i].lst >= lst2) { t[i].val = f; t[i].fst = fst2; t[i].lst = lst2; t[i].leaf = 1; return; } if (l <= b && e <= r && t[i].lst <= lst2 && t[i].fst <= fst2) return; ppg(i, b, e); if (l < (b+e)/2) mn(l, r, f, 2*i+1, b, (b+e)/2); if ((b+e)/2 < r) mn(l, r, f, 2*i+2, (b+e)/2, e); merge(i); } void mn(int l, int r, pll f) { mn(l, r, f, 0, 0, sz); } ll get(int p, int i, int b, int e) { if (t[i].leaf) return eval(t[i].val, p); ppg(i, b, e); if (p < (b+e)/2) return get(p, 2*i+1, b, (b+e)/2); else return get(p, 2*i+2, (b+e)/2, e); } ll get(int p) { return get(p, 0, 0, sz); } } namespace rmq { const int lg = 20; pii mx[lg][N]; void make(vector<int> a) { int n = a.size(); Loop (i,0,n) mx[0][i] = {a[i], i}; Loop (i,0,lg-1) { for (int j = 0; j + (2 << i) <= n; ++j) mx[i+1][j] = max(mx[i][j], mx[i][j+(1<<i)]); } } pii get(int l, int r) { int k = __lg(r-l); return max(mx[k][l], mx[k][r-(1<<k)]); } } ll arr[N]; namespace cart { pii t[N]; vector<pair<ll *, int>> queryl[N]; vector<pair<ll *, int>> queryr[N]; int rt; int sz; void make(int &ans, int l, int r) { if (l >= r) { ans = -1; return; } ans = rmq::get(l, r).second; make(t[ans].first, l, ans); make(t[ans].second, ans+1, r); } void make(int n) { sz = n; make(rt, 0, sz); } void dfs(int v, int l, int r, void (*merge)(int, int, int)) { if (v == -1) return; dfs(t[v].first, l, v, merge); dfs(t[v].second, v+1, r, merge); merge(v, l, r); } void mergel(int v, int l, int r) { seg::add(v, r, (v-l+1)*arr[v]); if (v != l) { ll x = seg::get(v-1); seg::mn(v, r, pll{arr[v], x - (v-1)*arr[v]}); } for (auto [p, pos] : queryl[v]) *p = seg::get(pos); } void merger(int v, int l, int r) { seg::add(l, v+1, (r-v)*arr[v]); if (v != r-1) { ll x = seg::get(v+1); seg::mn(l, v+1, pll{-arr[v], x + (v+1)*arr[v]}); } for (auto [p, pos] : queryr[v]) *p = seg::get(pos); } void answer() { seg::init(sz); dfs(rt, 0, sz, mergel); seg::init(sz); dfs(rt, 0, sz, merger); } } ll Ql[N], Qr[N]; std::vector<long long> minimum_costs(std::vector<int> H, std::vector<int> L, std::vector<int> R) { int n = H.size(); Loop (i,0,n) arr[i] = H[i]; rmq::make(H); cart::make(n); int q = L.size(); Loop (i,0,q) { int l = L[i]; int r = R[i]+1; int v = rmq::get(l, r).second; if (l < v) { cart::queryr[cart::t[v].first] .push_back({&Ql[i], l}); } if (v < r-1) { cart::queryl[cart::t[v].second] .push_back({&Qr[i], r-1}); } } cart::answer(); vector<ll> ans(q); Loop (i,0,q) { int l = L[i]; int r = R[i]+1; int v = rmq::get(l, r).second; ans[i] = arr[v] * (r-l); if (l < v) ans[i] = min(ans[i], Ql[i] + arr[v] * (r-v)); if (v < r-1) ans[i] = min(ans[i], Qr[i] + arr[v] * (v-l+1)); } 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...