제출 #799549

#제출 시각아이디문제언어결과실행 시간메모리
799549PixelCatAncient Books (IOI17_books)C++14
100 / 100
132 ms46284 KiB
#include "books.h" #ifdef NYAOWO #include "grader.cpp" #endif #include <bits/stdc++.h> #define For(i, a, b) for(int i = a; i <= b; i++) #define Forr(i, a, b) for(int i = a; i >= b; i--) #define F first #define S second #define all(x) x.begin(), x.end() #define sz(x) ((int)x.size()) #define eb emplace_back #define int LL using namespace std; using i32 = int32_t; using LL = long long; using pii = pair<int, int>; const int MAXN = 1'000'000; const int INF = 1e18; LL minimum_walk(vector<i32> p, i32 s) { assert(s >= 0); int n = sz(p); int ans = 0; vector<int> cid(n, -1); vector<pii> range; For(i, 0, n - 1) if(p[i] != i && cid[i] == -1) { int cur = i; int l = n + 1; int r = -1; do { l = min(l, cur); r = max(r, cur); ans += abs(p[cur] - cur); cur = p[cur]; cid[cur] = sz(range); } while(cur != i); range.eb(l, r); } if(sz(range) == 0) return 0; int L = 0, R = n - 1; while(cid[L] == -1) L++; while(cid[R] == -1) R--; L = min(L, (int)s); R = max(R, (int)s); cerr << L << " " << R << "\n"; vector<int> nxtl(n), nxtr(n); nxtl[0] = -INF; For(i, 1, n - 1) { if(cid[i - 1] != -1) nxtl[i] = i - 1; else nxtl[i] = nxtl[i - 1]; } nxtr[n - 1] = INF; Forr(i, n - 2, 0) { if(cid[i + 1] != -1) nxtr[i] = i + 1; else nxtr[i] = nxtr[i + 1]; } // For(i, 0, n - 1) cerr << nxtl[i] << " \n"[i == n - 1]; // For(i, 0, n - 1) cerr << nxtr[i] << " \n"[i == n - 1]; // return 0; auto walk = [&](int l, int r, pii target) { int tl, tr; tie(tl, tr) = target; tl = min(tl, l); tr = max(tr, r); // cerr << l << " " << r << " " << tl << " " << tr << "\n"; while(l > tl || r < tr) { if(l > tl) { l--; if(cid[l] != -1) { tl = min(tl, range[cid[l]].F); tr = max(tr, range[cid[l]].S); } } else { r++; if(cid[r] != -1) { tl = min(tl, range[cid[r]].F); tr = max(tr, range[cid[r]].S); } } } return pii(l, r); }; int l = s, r = s; if(cid[s] != -1) { tie(l, r) = walk(l, r, range[cid[s]]); } while(l > L || r < R) { int cl = 0; int l2, r2; l2 = l; r2 = r; if(l2 == L) cl = INF; while(r2 == r && l2 != L) { cl += (l2 - nxtl[l2]) * 2; l2 = nxtl[l2]; tie(l2, r2) = walk(l2, r2, range[cid[l2]]); } int cr = 0; int l3, r3; l3 = l; r3 = r; if(r3 == R) cr = INF; while(l3 == l && r3 != R) { cr += (nxtr[r3] - r3) * 2; r3 = nxtr[r3]; tie(l3, r3) = walk(l3, r3, range[cid[r3]]); } if(cl < cr) { ans += cl; tie(l, r) = walk(l, r, pii(l2, r2)); } else { ans += cr; tie(l, r) = walk(l, r, pii(l3, r3)); } } 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...