Submission #208872

#TimeUsernameProblemLanguageResultExecution timeMemory
208872rama_pangAncient Books (IOI17_books)C++14
100 / 100
261 ms26748 KiB
#include "books.h" #include <bits/stdc++.h> using namespace std; using lint = long long; void extend(int &l, int &r, vector<int> &C, vector<int> &L, vector<int> &R) { int ll = min({l, L[C[l]], L[C[r]]}); int rr = max({r, R[C[l]], R[C[r]]}); while (ll < l || r < rr) { if (ll < l) l--; if (r < rr) r++; ll = min({ll, L[C[l]], L[C[r]]}); rr = max({rr, R[C[l]], R[C[r]]}); } } int connect(int l, int r, int target_l, int target_r, vector<int> &C, vector<int> &L, vector<int> &R) { int cost = 0; do { extend(l, r, C, L, R); int cost_l = 0, cost_r = 0; bool next_l = false; int l_l = l, r_l = r; while (true) { if (l_l <= target_l) break; l_l--; cost_l += 2; extend(l_l, r_l, C, L, R); if (r < r_l) { next_l = true; break; } } bool next_r = false; int l_r = l, r_r = r; while (true) { if (target_r <= r_r) break; r_r++; cost_r += 2; extend(l_r, r_r, C, L, R); if (l_r < l) { next_r = true; break; } } if (next_l && next_r) { cost += min(cost_l, cost_r); // walking to shortest one, since the cycles overlap we need no additional cost } else { cost += cost_l + cost_r; // we must walk both ways } l = min(l_l, l_r); r = max(r_l, r_r); } while (target_l < l || r < target_r); return cost; } lint minimum_walk(vector<int> p, int s) { lint ans = 0; int n = p.size(); vector<int> cycle(n, -1); vector<int> L, R; // left and rightmost books in cycle int c = 0; // cycle count int target_l = s, target_r = s; for (int i = 0; i < n; i++) { ans += abs(i - p[i]); if (cycle[i] == -1) { L.emplace_back(i); R.emplace_back(i); int j = i; do { cycle[j] = c; L[c] = min(L[c], j); R[c] = max(R[c], j); j = p[j]; } while (j != i); if (p[i] != i) { target_l = min(target_l, L[c]); target_r = max(target_r, R[c]); } c++; } } return ans + connect(s, s, target_l, target_r, cycle, L, R); }
#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...