Submission #561375

#TimeUsernameProblemLanguageResultExecution timeMemory
561375piOOERainforest Jumps (APIO21_jumps)C++17
81 / 100
4074 ms47992 KiB
#include "jumps.h" #include <bits/stdc++.h> using namespace std; #define all(x) begin(x), end(x) const int logn = 19, N = 200001; int h[N], jump[logn][N], R[N], L[N], spt[logn][N], n, jmp[logn][N]; const int infI = 1e9 + 7; bool okk = true; int Min(int i, int j) { return h[i] < h[j] ? i : j; } int Max(int i, int j) { return h[i] > h[j] ? i : j; } int get_max(int l, int r) { if (r <= l) return -1; int sz = __lg(r - l); return Max(spt[sz][l], spt[sz][r - (1 << sz)]); } void init(int nn, vector<int> H) { n = nn; for (int i = 0; i < n; ++i) { h[i] = H[i]; okk &= (H[i] == i + 1); } vector<int> st; for (int i = 0; i < n; ++i) { while (!st.empty() && h[st.back()] < h[i]) { R[st.back()] = i; st.pop_back(); } if (st.empty()) { L[i] = -1; } else { L[i] = st.back(); } st.push_back(i); } for (int i: st) { R[i] = n; } st.clear(); for (int i = 0; i < n; ++i) { if (R[i] == n) jump[0][i] = L[i]; else if (L[i] == -1) jump[0][i] = R[i]; else jump[0][i] = Max(L[i], R[i]); jmp[0][i] = R[i]; spt[0][i] = i; } jmp[0][n] = n; jump[0][n] = -1; for (int j = 1; j < logn; ++j) { for (int i = 0; i <= n; ++i) { if (jump[j - 1][i] != -1) jump[j][i] = jump[j - 1][jump[j - 1][i]]; else jump[j][i] = -1; jmp[j][i] = jmp[j - 1][jmp[j - 1][i]]; } } for (int j = 1; j < logn; ++j) { for (int i = 0; i + (1 << j) <= n; ++i) { spt[j][i] = Max(spt[j - 1][i], spt[j - 1][i + (1 << (j - 1))]); } } } int minimum_jumps(int A, int B, int C, int D) { if (okk) { return C - B; } ++D, ++B; int mxcd = get_max(C, D); int lx = A - 1, rx = C; while (lx + 1 < rx) { int m = (lx + rx) >> 1; if (h[get_max(m, C)] < h[mxcd]) rx = m; else lx = m; } if (rx >= B) { return -1; } int i = get_max(rx, B); if (D == C + 1) { int ans = 0; for (int j = logn - 1; j > -1; --j) { if (jump[j][i] == -1 || h[jump[j][i]] >= h[C]) continue; ans += (1 << j); i = jump[j][i]; } assert(L[i] != C); assert(i < C); for (int j = logn - 1; j > -1; --j) { if (jmp[j][i] < C) { ans += (1 << j); i = jmp[j][i]; } } assert(R[i] == C); return ans + 1; } else { queue<int> q; vector<int> dist(n, infI); dist[i] = 0; q.push(i); while (!q.empty()) { int v = q.front(); q.pop(); if (L[v] != -1 && dist[L[v]] == infI) { q.push(L[v]); dist[L[v]] = dist[v] + 1; } if (R[v] != n && dist[R[v]] == infI) { q.push(R[v]); dist[R[v]] = dist[v] + 1; } } int ans = infI; for (int j = C; j < D; ++j) { ans = min(ans, dist[j]); } assert(ans != infI); 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...