Submission #1160495

#TimeUsernameProblemLanguageResultExecution timeMemory
1160495SmuggingSpunNile (IOI24_nile)C++20
100 / 100
244 ms13356 KiB
#include<bits/stdc++.h> #include "nile.h" using namespace std; typedef long long ll; template<class T>void minimize(T& a, T b){ if(a > b){ a = b; } } template<class T>void maximize(T& a, T b){ if(a < b){ a = b; } } const int INF = 1e9; vector<ll>calculate_costs(vector<int>W, vector<int>A, vector<int>B, vector<int>E){ int n = W.size(), q = E.size(); if(n == 1){ return vector<ll>(q, ll(A[0])); } if(q <= 5 && n <= 2000 && *max_element(W.begin(), W.end()) == 1){ ll ans = accumulate(B.begin(), B.end(), 0LL); if(n & 1){ int d = INF; for(int i = 0; i < n; i++){ minimize(d, A[i] - B[i]); } ans += d; } return vector<ll>(q, ans); } vector<int>p(n); iota(p.begin(), p.end(), 0); sort(p.begin(), p.end(), [&] (int i, int j){ return W[i] < W[j]; }); vector<int>pd(n - 1); iota(pd.begin(), pd.end(), 0); sort(pd.begin(), pd.end(), [&] (int i, int j){ return W[p[i + 1]] - W[p[i]] < W[p[j + 1]] - W[p[j]]; }); vector<int>pst(n - 2); iota(pst.begin(), pst.end(), 1); sort(pst.begin(), pst.end(), [&] (int i, int j){ return W[p[i + 1]] - W[p[i - 1]] < W[p[j + 1]] - W[p[j - 1]]; }); vector<vector<int>>st(4, vector<int>(n << 2, INF)); function<void(int, int, int, int, int, int)>update; update = [&] (int type, int id, int l, int r, int p, int x){ if(l == r){ st[type][id] = x; return; } int m = (l + r) >> 1; if(m < p){ update(type, id << 1 | 1, m + 1, r, p, x); } else{ update(type, id << 1, l, m, p, x); } st[type][id] = min(st[type][id << 1], st[type][id << 1 | 1]); }; function<int(int, int, int, int, int, int)>get; get = [&] (int type, int id, int l, int r, int u, int v){ if(l > v || r < u){ return INF; } if(u <= l && v >= r){ return st[type][id]; } int m = (l + r) >> 1; return min(get(type, id << 1, l, m, u, v), get(type, id << 1 | 1, m + 1, r, u, v)); }; for(int i = 0; i < n; i++){ update(i & 1, 1, 0, n - 1, i, A[p[i]] - B[p[i]]); } auto get_range = [&] (int l, int r){ return ((r - l) & 1) ? 0 : min(get(l & 1, 1, 0, n - 1, l, r), get(((l & 1) ^ 1) | 2, 1, 0, n - 1, l, r)); }; ll cur = accumulate(A.begin(), A.end(), 0LL); vector<int>lab(n), l(n), r(n); for(int i = 0; i < n; i++){ lab[i] = l[i] = r[i] = i; } auto find_set = [&] (int N){ while(N != lab[N]){ N = lab[N] = lab[lab[N]]; } return N; }; auto merge = [&] (int u, int v){ cur -= get_range(l[u = find_set(u)], r[u]) + get_range(l[v = find_set(v)], r[v]); minimize(l[lab[v] = u], l[v]); maximize(r[u], r[v]); cur += get_range(l[u], r[u]); }; vector<int>pq(q); iota(pq.begin(), pq.end(), 0); sort(pq.begin(), pq.end(), [&] (int i, int j){ return E[i] < E[j]; }); vector<ll>ans(q); int ipd = 0, ist = 0; for(int& iq : pq){ while(ist + 2 < n && W[p[pst[ist] + 1]] - W[p[pst[ist] - 1]] <= E[iq]){ int i = find_set(pst[ist]); cur -= get_range(l[i], r[i]); update((pst[ist] & 1) | 2, 1, 0, n - 1, pst[ist], A[p[pst[ist]]] - B[p[pst[ist]]]); cur += get_range(l[i], r[i]); ist++; } while(ipd + 1 < n && W[p[pd[ipd] + 1]] - W[p[pd[ipd]]] <= E[iq]){ merge(pd[ipd], pd[ipd] + 1); ipd++; } ans[iq] = cur; } 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...