Submission #838232

#TimeUsernameProblemLanguageResultExecution timeMemory
838232JohannAncient Books (IOI17_books)C++14
50 / 100
153 ms28028 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; 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); cycle(P[i], mini, maxi, cycleCnt); } 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]; 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; } vi maxL(N, s), maxR(N, s), cost(N, 0); if (vis[s] != -1) tie(maxL[s], maxR[s]) = borders[vis[s]]; for (int i = s + 1; i < N; ++i) { maxL[i] = maxL[i - 1], maxR[i] = maxR[i - 1], cost[i] = cost[i - 1]; if (maxR[i] < i) cost[i] += 2, maxR[i] = i; if (vis[i] != -1) maxL[i] = min(maxL[i], borders[vis[i]].first), maxR[i] = max(maxR[i], borders[vis[i]].second); } for (int i = s - 1; i >= 0; --i) { maxL[i] = maxL[i + 1], maxR[i] = maxR[i + 1], cost[i] = cost[i + 1]; if (maxL[i] > i) cost[i] += 2, maxL[i] = i; if (vis[i] != -1) maxL[i] = min(maxL[i], borders[vis[i]].first), maxR[i] = max(maxR[i], borders[vis[i]].second); } ll mincost = INF; int l = s, r = N - 1; while (l >= 0 && r >= 0) { int virtualL = min(maxL[l], maxL[maxL[r]]); if (max(maxR[l], maxR[r]) < R || virtualL > L) --l; else { ll tmp = safecost + cost[r]; if (l < maxL[r]) tmp += cost[l] - cost[maxL[r]]; mincost = min(mincost, tmp); --r; } } return mincost; }
#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...