Submission #561403

#TimeUsernameProblemLanguageResultExecution timeMemory
561403piOOERainforest Jumps (APIO21_jumps)C++17
100 / 100
1383 ms47972 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; 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]; } 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) { ++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); int mxx = get_max(i, C); for (int j = logn - 1; j > -1; --j) { if (C + (1 << j) <= n && h[get_max(C, C + (1 << j))] < h[mxx]) { C += (1 << j); } } //now C is the first correct index int ans = infI; int nw = 0; for (int j = logn - 1; j > -1; --j) { if (jump[j][i] == -1) continue; if (h[jump[j][i]] < h[C]) { nw += (1 << j); i = jump[j][i]; } } if (L[i] != -1 && h[L[i]] >= h[C] && h[L[i]] <= h[mxcd]) { ans = min(ans, nw + 2); //maybe we can just go one time left and one time right } for (int j = logn - 1; j > -1; --j) { if (jmp[j][i] < C) { nw += (1 << j); i = jmp[j][i]; } } return min(ans, nw + 1); }
#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...