Submission #1201071

#TimeUsernameProblemLanguageResultExecution timeMemory
1201071badge881Ancient Books (IOI17_books)C++20
100 / 100
627 ms102176 KiB
#include <bits/stdc++.h> #include "books.h" #define int long long using namespace std; const int maxn = 1e6 + 5, INF = 1e18; int n; int p[maxn], ll[maxn], rr[maxn], vis[maxn]; int fa[maxn], sz[maxn]; int rt(int u) { if (fa[u] == u) return u; return fa[u] = rt(fa[u]); } void merge(int u, int v) { u = rt(u), v = rt(v); if (u == v) return; if (sz[u] > sz[v]) swap(u, v); fa[u] = v; sz[v] += sz[u]; ll[v] = min(ll[u], ll[v]); rr[v] = max(rr[u], rr[v]); } int minimum_walk(vector<int32_t> P, int32_t S) { n = P.size(); for (int i=0;i<n;i++) p[i+1] = P[i] + 1; S++; for (int i=0;i<=n+1;i++) ll[i] = rr[i] = fa[i] = i, sz[i] = 1; int ans = 0, cnt = 0; for (int i=1;i<=n;i++) if (!vis[i]) { int u = i; while (true) { merge(u, i); vis[u] = true; int v = p[u]; ans += abs(v-u); if (v==i) break; u = v; } } set<int> s; s.insert(INF); for (int i=1;i<=n;i++) if (ll[rt(i)] == i) { int u = i, lim = rr[rt(i)]; vector<int> log; while (s.size() > 0) { int pos = *s.lower_bound(u); if (pos > lim) break; log.push_back(rt(pos)); u = rr[rt(pos)] + 1; } for (int j:log) merge(j, i); u = i; while (true) { s.insert(u); int v = p[u]; if (v == i) break; u = v; } } int lend = 1, rend = n; while (lend+1 <= n && p[lend] == lend) lend++; while (rend-1 >= 1 && p[rend] == rend) rend--; int l = ll[rt(S)], r = rr[rt(S)]; if (l >= lend && r <= rend) { merge(lend-1, rend+1); while (l >= lend && r <= rend) { int lcost = 0, rcost = 0; int lu = l; while (rr[rt(lu)] <= r) { lu = ll[rt(lu - 1)], lcost += 2; } if (lu == lend-1) lcost = INF; int ru = r; while (ll[rt(ru)] >= l) { ru = rr[rt(ru + 1)], rcost += 2; } if (ru == rend+1) rcost = INF; // cout << l << " " << r << endl; if (lcost == INF && rcost == INF) break; if (lcost < rcost) ans += lcost, l = ll[rt(lu)], r = rr[rt(lu)]; else ans += rcost, l = ll[rt(ru)], r = rr[rt(ru)]; } } while (l > lend) l = ll[rt(l-1)], ans += 2; while (r < rend) r = rr[rt(r+1)], ans += 2; 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...