제출 #1037720

#제출 시각아이디문제언어결과실행 시간메모리
1037720MilosMilutinovicText editor (CEOI24_editor)C++14
100 / 100
2527 ms271528 KiB
#include <bits/stdc++.h> using namespace std; const int MAX = 1000100; const int L = 21; const int inf = (int) 1e9; int n, sx, sy, fx, fy; int l[MAX], logs[MAX], mn[MAX][L], sz[MAX]; int prv[MAX], nxt[MAX]; vector<int> pos[MAX], dist[MAX]; priority_queue<array<int, 3>> pq; int Query(int l, int r) { int k = logs[r - l + 1]; return min(mn[l][k], mn[r - (1 << k) + 1][k]); } void Update(int i, int j, int d) { if (dist[i][j] > d) { dist[i][j] = d; pq.push({-dist[i][j], i, j}); } } int Index(int i, int v) { return (int) (lower_bound(pos[i].begin(), pos[i].end(), v) - pos[i].begin()); } bool Has(int i, int v) { int idx = Index(i, v); return 0 <= idx && idx < sz[i] && (pos[i][idx] == v); } int FindL(int i, int v) { if (v == 0) { return -1; } if (v == l[i]) { return prv[i]; } int low = 0, high = i - 1, p = -1; while (low <= high) { int mid = (low + high) >> 1; if (Query(mid, i - 1) <= v) { p = mid; low = mid + 1; } else { high = mid - 1; } } return p; } int FindR(int i, int v) { if (v == 0) { return n; } if (v == l[i]) { return nxt[i]; } int low = i + 1, high = n - 1, p = n; while (low <= high) { int mid = (low + high) >> 1; if (Query(i + 1, mid) <= v) { p = mid; high = mid - 1; } else { low = mid + 1; } } return p; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n; cin >> sx >> sy; --sx; --sy; cin >> fx >> fy; --fx; --fy; for (int i = 0; i < n; i++) { cin >> l[i]; } { vector<int> stk; for (int i = 0; i < n; i++) { while (!stk.empty() && l[stk.back()] > l[i]) { stk.pop_back(); } prv[i] = (stk.empty() ? -1 : stk.back()); stk.push_back(i); } } { vector<int> stk; for (int i = n - 1; i >= 0; i--) { while (!stk.empty() && l[stk.back()] > l[i]) { stk.pop_back(); } nxt[i] = (stk.empty() ? n : stk.back()); stk.push_back(i); } } for (int i = 0; i < n; i++) { if (i != fx && l[i] <= l[fx]) { pos[fx].push_back(l[i]); } } for (int i = 0; i < n; i++) { pos[i].push_back(0); pos[i].push_back(l[i]); if (sy <= l[i]) { pos[i].push_back(sy); } if (fy <= l[i]) { pos[i].push_back(fy); } sort(pos[i].begin(), pos[i].end()); pos[i].erase(unique(pos[i].begin(), pos[i].end()), pos[i].end()); } for (int i = 0; i < n; i++) { sz[i] = (int) pos[i].size(); } for (int i = 2; i <= n; i++) { logs[i] = logs[i >> 1] + 1; } for (int i = 0; i < n; i++) { mn[i][0] = l[i]; } for (int j = 1; j < L; j++) { for (int i = 0; i + (1 << j) <= n; i++) { mn[i][j] = min(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]); } } for (int i = 0; i < n; i++) { dist[i] = vector<int>(sz[i], inf); } for (int i = 0; i < sz[sx]; i++) { if (pos[sx][i] == sy) { dist[sx][i] = 0; pq.push({0, sx, i}); } } while (!pq.empty()) { int d = -pq.top()[0]; int i = pq.top()[1]; int j = pq.top()[2]; pq.pop(); if (dist[i][j] != d) { continue; } if (j > 0) { Update(i, j - 1, dist[i][j] + pos[i][j] - pos[i][j - 1]); } else if (i > 0) { Update(i - 1, sz[i - 1] - 1, dist[i][j] + 1); } if (j + 1 < sz[i]) { Update(i, j + 1, dist[i][j] + pos[i][j + 1] - pos[i][j]); } else if (i + 1 < n) { Update(i + 1, 0, dist[i][j] + 1); } if (i > 0 && Has(i - 1, pos[i][j])) { Update(i - 1, Index(i - 1, pos[i][j]), dist[i][j] + 1); } if (i + 1 < n && Has(i + 1, pos[i][j])) { Update(i + 1, Index(i + 1, pos[i][j]), dist[i][j] + 1); } { int idx = FindL(i, pos[i][j]); if (idx != -1) { Update(idx, sz[idx] - 1, dist[i][j] + i - idx); } if (idx < fx && fx < i && Has(fx, pos[i][j])) { Update(fx, Index(fx, pos[i][j]), dist[i][j] + i - fx); } } { int idx = FindR(i, pos[i][j]); if (idx != n) { Update(idx, sz[idx] - 1, dist[i][j] + idx - i); } if (i < fx && fx < idx && Has(fx, pos[i][j])) { Update(fx, Index(fx, pos[i][j]), dist[i][j] + fx - i); } } } for (int i = 0; i < sz[fx]; i++) { if (pos[fx][i] == fy) { cout << dist[fx][i] << '\n'; } } return 0; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...