Submission #838317

#TimeUsernameProblemLanguageResultExecution timeMemory
838317JohannAncient Books (IOI17_books)C++14
50 / 100
249 ms51608 KiB
#include "books.h" #include "bits/stdc++.h" using namespace std; typedef long long ll; typedef vector<ll> vi; typedef vector<vi> vvi; typedef pair<ll, ll> pii; typedef vector<pii> vpii; typedef vector<vpii> vvpii; #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() const ll INF = 1LL << 60; int N; ll safecost; vi vis, P; struct unionfind { vi arr; vpii stuff; void init(int size) { arr.resize(size); stuff.resize(size); for (int i = 0; i < size; ++i) arr[i] = i, stuff[i] = {i, i}; } int find(int i) { return arr[i] = (arr[i] == i) ? i : find(arr[i]); } void unite(int a, int b) { a = find(a), b = find(b); stuff[a] = {min(stuff[a].first, stuff[b].first), max(stuff[a].second, stuff[b].second)}; arr[b] = a; } pii border(int i) { return stuff[find(i)]; } }; unionfind uf; void cycle(int i, int &mini, int &maxi, int cycleCnt) { if (vis[i] != -1) return; mini = min(mini, i); maxi = max(maxi, i); vis[i] = cycleCnt; safecost += (ll)abs(P[i] - i); uf.unite(i, P[i]); cycle(P[i], mini, maxi, cycleCnt); } vvpii adj; long long minimum_walk(std::vector<int> p, int s) { N = sz(p); P.resize(N); for (int i = 0; i < N; ++i) P[i] = p[i]; uf.init(N); vis.assign(N, -1); ll L = INF, R = -1; safecost = 0; vpii borders; for (int i = 0, mini, maxi; i < N; ++i) { if (P[i] != i) L = min(L, (ll)i), R = max(R, (ll)i); if (vis[i] == -1 && P[i] != i) { mini = maxi = i; cycle(i, mini, maxi, sz(borders)); borders.push_back({mini, maxi}); } } if (borders.empty()) return 0; if (s <= L || s >= R) { if (s >= R) { s = N - s; for (int i = 0, l, r; i < sz(borders); ++i) { tie(l, r) = borders[i]; borders[i] = {N - r, N - l}; } } sort(all(borders)); ll pos = s; for (pii b : borders) { safecost += 2 * max(0LL, b.first - pos); pos = max(pos, b.second); } return safecost; } stack<int> st; for (int i = R; i >= L; --i) { while (!st.empty() && st.top() <= uf.border(i).second) { int b = st.top(); if (b != uf.border(b).first) uf.unite(i, b); st.pop(); } st.push(i); } ll l = s, r = s; ll nl = l, nr = r; do { if (nl >= 0 && nl != P[nl] && (uf.border(nl).first < l || uf.border(nl).second > r)) { safecost += 2 * (l - nl); nl = l = min(l, uf.border(nl).first); nr = r = max(r, uf.border(nl).second); } else if (nr < N && nr != P[nr] && (uf.border(nr).first < l || uf.border(nr).second > r)) { safecost += 2 * (nr - r); nl = l = min(l, uf.border(nr).first); nr = r = max(r, uf.border(nr).second); } else --nl, ++nr; } while (L < l || r < R); return safecost; }
#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...