제출 #1244655

#제출 시각아이디문제언어결과실행 시간메모리
1244655raphaelpPassport (JOI23_passport)C++20
100 / 100
951 ms17396 KiB
#include <bits/stdc++.h> using namespace std; class SegTree { private: int N, type, inf; vector<int> st, node; int merge(int a, int b) { if (type == 0) return max(a, b); else return min(a, b); } int r(int x) { return (x << 1) + 1; } int l(int x) { return (x << 1); } void update(int L, int R, int a, int val, int x) { if (L > a || R < a) return; if (L == R) { st[x] = val; node[x] = L; } else { int m = (L + R) / 2; update(L, m, a, val, l(x)); update(m + 1, R, a, val, r(x)); st[x] = merge(st[l(x)], st[r(x)]); if (st[x] == st[l(x)]) node[x] = node[l(x)]; else node[x] = node[r(x)]; } } int RMQ(int L, int R, int a, int b, int val, int x) { if (L > b || R < a) return -1; if (L >= a && R <= b) { if (merge(st[x], val) == st[x]) return node[x]; else return -1; } int m = (L + R) / 2; return max(RMQ(L, m, a, b, val, l(x)), RMQ(m + 1, R, a, b, val, r(x))); } public: SegTree(int x, int t) { N = pow(2, ceil(log2(x))); type = t; inf = 1000000000 * t; st.assign(2 * N, inf); node.assign(2 * N, -1); } void udpate(int a, int val) { update(0, N - 1, a, val, 1); } int RMQ(int a, int b, int val) { if (a > b) return -1; return RMQ(0, N - 1, a, b, val, 1); } }; int main() { int N; cin >> N; vector<int> L(N), R(N); for (int i = 0; i < N; i++) { cin >> L[i] >> R[i]; L[i]--, R[i]--; } vector<int> minL(N, 1000000000), minR(N, 1000000000); minL[0] = 0, minR[N - 1] = 0; SegTree MINN(N, 1), MAXX(N, 0); for (int i = 1; i < N; i++) { MINN.udpate(i, L[i]); MAXX.udpate(i, R[i]); } queue<int> Q; Q.push(0); while (!Q.empty()) { int x = Q.front(); Q.pop(); int y = MINN.RMQ(x + 1, N - 1, x); while (y != -1) { MINN.udpate(y, 1000000000); MAXX.udpate(y, -1); minL[y] = minL[x] + 1; Q.push(y); y = MINN.RMQ(x + 1, N - 1, x); } y = MAXX.RMQ(0, x - 1, x); while (y != -1) { MINN.udpate(y, 1000000000); MAXX.udpate(y, -1); minL[y] = minL[x] + 1; Q.push(y); y = MAXX.RMQ(0, x - 1, x); } } for (int i = 0; i < N - 1; i++) { MINN.udpate(i, L[i]); MAXX.udpate(i, R[i]); } Q.push(N - 1); while (!Q.empty()) { int x = Q.front(); Q.pop(); int y = MINN.RMQ(x + 1, N - 1, x); while (y != -1) { MINN.udpate(y, 1000000000); MAXX.udpate(y, -1); minR[y] = minR[x] + 1; Q.push(y); y = MINN.RMQ(x + 1, N - 1, x); } y = MAXX.RMQ(0, x - 1, x); while (y != -1) { MINN.udpate(y, 1000000000); MAXX.udpate(y, -1); minR[y] = minR[x] + 1; Q.push(y); y = MAXX.RMQ(0, x - 1, x); } } minL[0] = minR[N - 1] = 1; for (int i = 0; i < N; i++) { MINN.udpate(i, L[i]); MAXX.udpate(i, R[i]); } priority_queue<pair<int, int>> PQ; vector<int> ans(N, 1000000000); for (int i = 0; i < N; i++) PQ.push({-(minL[i] + minR[i] - 1), i}); while (!PQ.empty()) { int x = PQ.top().second, t = -PQ.top().first; PQ.pop(); if (t >= ans[x]) continue; ans[x] = t; MINN.udpate(x, 1000000000); MAXX.udpate(x, -1); int y = MINN.RMQ(x + 1, N - 1, x); while (y != -1) { MINN.udpate(y, 1000000000); MAXX.udpate(y, -1); PQ.push({-ans[x] - 1, y}); y = MINN.RMQ(x + 1, N - 1, x); } y = MAXX.RMQ(0, x - 1, x); while (y != -1) { MINN.udpate(y, 1000000000); MAXX.udpate(y, -1); PQ.push({-ans[x] - 1, y}); y = MAXX.RMQ(0, x - 1, x); } } int Qs; cin >> Qs; for (int i = 0; i < Qs; i++) { int x; cin >> x; if (ans[x - 1] >= 1000000000) cout << -1 << '\n'; else cout << ans[x - 1] << '\n'; } }
#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...