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

#TimeUsernameProblemLanguageResultExecution timeMemory
1105544Lib_StealMeetings (IOI18_meetings)C++17
60 / 100
4003 ms786432 KiB
#include<bits/stdc++.h> #define L(i, j, k) for(int i = (j); i <= (k); ++i) #define R(i, j, k) for(int i = (j); i >= (k); --i) #define ll long long #define vi vector <int> #define sz(a) ((int) (a).size()) #define QAQ using namespace std; const int N = 7.5e5 + 7, M = 1 << 24; const ll inf = 1e18; struct RMQ { int a[N], mx[20][N], lg[N]; void init (int n) { L(i, 2, n) lg[i] = lg[i >> 1] + 1; L(i, 1, n) mx[0][i] = i; L(i, 1, 19) L(j, 1, n - (1 << i) + 1) mx[i][j] = a[mx[i - 1][j]] > a[mx[i - 1][j + (1 << (i - 1))]] ? mx[i - 1][j] : mx[i - 1][j + (1 << (i - 1))]; } inline int queryp (int l, int r) { int p = lg[r - l + 1]; return a[mx[p][l]] > a[mx[p][r - (1 << p) + 1]] ? mx[p][l] : mx[p][r - (1 << p) + 1]; } inline int query (int l, int r) { return a[queryp (l, r)]; } } a; int n, q; map < pair < int, int >, ll > mp; int h[N]; ll DFS (int l, int r) { if (l > r) return 0; if (mp.count({l, r})) return mp[{l, r}]; if (l == r) return h[l]; int mi = a.queryp(l, r); return mp[{l, r}] = min(DFS(l, mi - 1) + (ll) (r - mi + 1) * h[mi], DFS(mi + 1, r) + (ll) (mi - l + 1) * h[mi]); } struct wk { bool op; inline int gmx(int l, int r) { return op ? n - a.queryp(n - r + 1, n - l + 1) + 1 : a.queryp (l, r); } int h[N], stk[N], tp, fa[N], dep[N]; ll fw[N], all[N]; vi e[N]; int dfn[N], MP[N], hv[N], siz[N], mxto[N], idt; struct line { int k; ll b; line (int K = 0, ll B = 0) { k = K, b = B; } inline ll get (int w) { return b + (ll) k * w; } }; ll inter (line u, line v) { return (u.b - v.b) / (v.k - u.k); } int hd[1 << 21], ch[M][2], tot, seg[M]; line f[N]; void Add(int &id, int L, int R, int p) { ll nl = f[seg[id]].get(L), nr = f[seg[id]].get(R), pl = f[p].get(L), pr = f[p].get(R); if(id && nl <= pl && nr <= pr) return; int x = ++tot; ch[x][0] = ch[id][0], ch[x][1] = ch[id][1], seg[x] = seg[id]; if(!id || (nl >= pl && nr >= pr)) return seg[x] = p, id = x, void(); id = x; int mid = (L + R) >> 1; ll it = inter(f[seg[x]], f[p]); if(it <= mid) { if(nl <= pl) Add(ch[x][0], L, mid, seg[x]), seg[x] = p; else Add(ch[x][0], L, mid, p); } else { if(nl <= pl) Add(ch[x][1], mid + 1, R, p); else Add(ch[x][1], mid + 1, R, seg[x]), seg[x] = p; } } ll Qry(int id, int L, int R, int pos) { if(!id) return inf; if(L == R) return f[seg[id]].get(pos); int mid = (L + R) >> 1; if(pos <= mid) return min(f[seg[id]].get(pos), Qry(ch[id][0], L, mid, pos)); else return min(f[seg[id]].get(pos), Qry(ch[id][1], mid + 1, R, pos)); } int merge (int x, int y, int L, int R) { if(!x || !y) return x | y; int nw = ++tot, mid = (L + R) >> 1; ch[nw][0] = merge(ch[x][0], ch[y][0], L, mid); ch[nw][1] = merge(ch[x][1], ch[y][1], mid + 1, R); seg[nw] = seg[x]; Add (nw, L, R, seg[y]); return nw; } void Build (int x, int L, int R) { if(L == R) return f[L] = line (-h[MP[L]], fw[MP[L]]), hd[x] = ++tot, seg[hd[x]] = L, void (); int mid = (L + R) >> 1; Build (x << 1, L, mid); Build (x << 1 | 1, mid + 1, R); hd[x] = merge (hd[x << 1], hd[x << 1 | 1], 1, n); } ll query (int x, int L, int R, int l, int r, int p) { if(l <= L && R <= r) return Qry (hd[x], 1, n, p); int mid = (L + R) >> 1; ll ret = inf; if(l <= mid) ret = min(ret, query (x << 1, L, mid, l, r, p)); if(r > mid) ret = min(ret, query (x << 1 | 1, mid + 1, R, l, r, p)); return ret; } void dfs (int x) { siz[x] = 1; for (auto v : e[x]) { dep[v] = dep[x] + 1, dfs(v), siz[x] += siz[v]; if(siz[v] > siz[hv[x]]) hv[x] = v; } } void dfs2(int x) { dfn[x] = ++idt; MP[idt] = x; if(hv[x]) mxto[hv[x]] = mxto[x], dfs2 (hv[x]); for (auto v : e[x]) if(v != hv[x]) mxto[v] = v, dfs2 (v); } void init () { L(i, 1, n) { while (tp > 0 && h[i] >= h[stk[tp]] + op) fa[stk[tp]] = i, -- tp; stk[++tp] = i; } R(i, n, 1) if(fa[i]) all[i] = (ll) (fa[i] - i) * h[i] + all[fa[i]], fw[i] = (op ? DFS(n - (fa[i] - 1) + 1, n - i + 1) : DFS(i, fa[i] - 1)) + all[fa[i]]; L(i, 1, n) fw[i] += (ll) h[i] * i; L(i, 1, n) if(fa[i]) e[fa[i]].push_back(i); R(i, n, 1) if(!dfn[i]) dfs (i), mxto[i] = i, dfs2 (i); Build (1, 1, n); } ll query (int l, int r) { // r : max if(l == r) return 0; ll ns = 1e18; int u = l; for (; mxto[u] != mxto[r]; u = fa[mxto[u]]) ns = min(ns, query (1, 1, n, dfn[mxto[u]], dfn[u], l)); if(dfn[r] < dfn[u]) ns = min(ns, query (1, 1, n, dfn[r] + 1, dfn[u], l)); // for (int u = l; u != r; u = fa[u]) ns = min(ns, fw[u] - (ll) h[u] * l); return ns - all[r]; } } u, v; vector < ll > minimum_costs (vi H, vi L, vi R) { n = sz(H), q = sz(L); L(i, 1, n) h[i] = H[i - 1], u.h[i] = v.h[n - i + 1] = h[i], a.a[i] = h[i]; a.init(n); v.op = true; u.init(), v.init(); vector < ll > ns (q); L(t, 0, q - 1) { int l = L[t], r = R[t]; ++ l, ++ r; int p = a.queryp(l, r); ns[t] = min(u.query(l, p) + (ll) h[p] * (r - p + 1), v.query(n - r + 1, n - p + 1) + (ll) h[p] * (p - l + 1)); } return ns; }
#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...