Submission #964639

#TimeUsernameProblemLanguageResultExecution timeMemory
964639kilkuwuRainforest Jumps (APIO21_jumps)C++17
48 / 100
959 ms127316 KiB
#include "jumps.h" #include <bits/stdc++.h> template<typename T, typename F> struct SparseTable { std::vector<std::vector<T>> t; SparseTable() {} SparseTable(const std::vector<T>& a) : t(std::__lg(a.size()) + 1, std::vector<T>(a)) { for (int k = 0; k + 1 < (int) t.size(); k++) for (int i = 0; i + (1 << k) < (int) a.size(); i++) t[k + 1][i] = F()(t[k][i], t[k][i + (1 << k)]); } T query(int l, int r) { int k = std::__lg(r - l + 1); return F()(t[k][l], t[k][r - (1 << k) + 1]); } }; template<typename T> struct MaxMerge { T operator()(const T& a, const T& b) { return std::max<T>(a, b); } }; template<typename T> struct MinMerge { T operator()(const T& a, const T& b) { return std::min<T>(a, b); } }; constexpr int mxN = 200002, LOG = 20; int L[LOG][mxN]; int cntL[LOG][mxN]; int R[LOG][mxN]; int cntR[LOG][mxN]; int N; int prefer[LOG][mxN]; int cnt[LOG][mxN]; std::vector<int> H; using ST = SparseTable<std::pair<int, int>, MaxMerge<std::pair<int, int>>>; using ST2 = SparseTable<std::pair<int, int>, MinMerge<std::pair<int, int>>>; ST tab; void init(int _N, std::vector<int> _H) { N = _N; H = _H; std::stack<int> st; for (int i = 0; i < N; i++) { while (st.size() && H[st.top()] <= H[i]) { st.pop(); } L[0][i] = st.empty() ? i : st.top(); cntL[0][i] = L[0][i] != i; st.push(i); } while (st.size()) st.pop(); for (int i = N - 1; i >= 0; i--) { while (st.size() && H[st.top()] <= H[i]) { st.pop(); } R[0][i] = st.empty() ? i : st.top(); cntR[0][i] = R[0][i] != i; st.push(i); } std::vector<std::pair<int, int>> base(N); for (int i = 0; i < N; i++) base[i] = {H[i], i}; tab = base; for (int i = 0; i < N; i++) { if (L[0][i] == i && R[0][i] == i) { prefer[0][i] = i; cnt[0][i] = 0; continue; } cnt[0][i] = 1; if (L[0][i] == i) { prefer[0][i] = R[0][i]; } else if (R[0][i] == i) { prefer[0][i] = L[0][i]; } else { prefer[0][i] = H[L[0][i]] > H[R[0][i]] ? L[0][i] : R[0][i]; } } for (int k = 0; k + 1 < LOG; k++) { for (int i = 0; i < N; i++) { prefer[k + 1][i] = prefer[k][prefer[k][i]]; cnt[k + 1][i] = cnt[k][i] + cnt[k][prefer[k][i]]; L[k + 1][i] = L[k][L[k][i]]; R[k + 1][i] = R[k][R[k][i]]; cntL[k + 1][i] = cntL[k][i] + cntL[k][L[k][i]]; cntR[k + 1][i] = cntR[k][i] + cntR[k][R[k][i]]; } } } int minimum_jumps(int A, int B, int C, int D) { int sz_mid = C - B - 1; auto br = tab.query(C, D); int thres = H[B]; if (sz_mid > 0) { auto bmid = tab.query(B + 1, C - 1); thres = std::max(thres, bmid.first); } if (thres >= br.first) return -1; int lb = C, rb = br.second; while (lb < rb) { int m = (lb + rb) / 2; if (tab.query(C, m).first > thres) { rb = m; } else { lb = m + 1; } } int f = rb; int e = br.second; lb = A, rb = B; while (lb < rb) { int m = (lb + rb) / 2; if (tab.query(m, B).first < br.first) { rb = m; } else { lb = m + 1; } } auto best = tab.query(rb, B); int jumps = 0; int u = best.second; for (int k = LOG - 1; k >= 0; k--) { int to = prefer[k][u]; if (H[to] >= br.first) continue; if (to >= f) continue; // we don't want it to go past this one jumps += cnt[k][u]; u = to; } for (int k = LOG - 1; k >= 0; k--) { int to = R[k][u]; if (to >= f) continue; jumps += cntR[k][u]; u = to; } jumps++; return jumps; }

Compilation message (stderr)

jumps.cpp: In function 'int minimum_jumps(int, int, int, int)':
jumps.cpp:133:7: warning: unused variable 'e' [-Wunused-variable]
  133 |   int e = br.second;
      |       ^
#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...