제출 #716166

#제출 시각아이디문제언어결과실행 시간메모리
716166schiftyfive4밀림 점프 (APIO21_jumps)C++14
100 / 100
1593 ms98744 KiB
#include "jumps.h" #include <bits/stdc++.h> using namespace std; #ifdef LOCAL #include "debug.hpp" #else #define debug(...) "MJ >> LAMELO" #endif template <typename T, class F = function<T(const T&, const T&)>> struct sparse_table { int n; vector<vector<T>> mat; F func; sparse_table() {} sparse_table(const vector<T>& a, const F& f) : func(f) { n = static_cast<int>(a.size()); int max_log = 32 - __builtin_clz(n); mat.resize(max_log); mat[0] = a; for (int j = 1; j < max_log; j++) { mat[j].resize(n - (1 << j) + 1); for (int i = 0; i <= n - (1 << j); i++) { mat[j][i] = func(mat[j - 1][i], mat[j - 1][i + (1 << (j - 1))]); } } } T get(int L, int R) const { assert(0 <= L && L <= R && R <= n - 1); int lg = 32 - __builtin_clz(R - L + 1) - 1; return func(mat[lg][L], mat[lg][R - (1 << lg) + 1]); } }; const int lg = 20; vector<int> h; vector<vector<int>> g; vector<vector<int>> go_low; vector<vector<int>> go_high; vector<vector<int>> go_right; sparse_table<int> st; int n; void init(int N, vector<int> H) { n = N; h = H; h.push_back(1e9); g.resize(n + 1); vector<int> t; for (int i = 0; i < n; i++) { while (!t.empty() && h[i] > h[t.back()]) { t.pop_back(); } if (!t.empty()) { g[i].push_back(t.back()); } t.push_back(i); } go_right = vector<vector<int>>(n + 1, vector<int>(lg)); t.clear(); for (int i = n - 1; i >= 0; i--) { go_right[i][0] = i; while (!t.empty() && h[i] > h[t.back()]) { t.pop_back(); } if (!t.empty()) { g[i].push_back(t.back()); go_right[i][0] = t.back(); } t.push_back(i); } for (int i = 0; i < n; i++) { if (g[i].size() == 2 && h[g[i][0]] > h[g[i][1]]) { swap(g[i][0], g[i][1]); } } go_low = vector<vector<int>>(n + 1, vector<int>(lg)); go_high = vector<vector<int>>(n + 1, vector<int>(lg)); for (int i = 0; i <= n; i++) { go_low[i][0] = go_high[i][0] = n; if (g[i].size() > 0) { go_low[i][0] = g[i][0]; } if (g[i].size() > 1){ go_high[i][0] = g[i][1]; } } for (int b = 1; b < lg; b++) { for (int i = 0; i <= n; i++) { go_low[i][b] = go_low[go_low[i][b - 1]][b - 1]; go_high[i][b] = go_high[go_high[i][b - 1]][b - 1]; go_right[i][b] = go_right[go_right[i][b - 1]][b - 1]; } } vector<int> p(n); iota(p.begin(), p.end(), 0); st = sparse_table<int>(p, [&](int i, int j) { return h[i] > h[j] ? i : j; }); } int minimum_jumps(int a, int b, int c, int d) { int x = st.get(c, d); if (h[st.get(b, c - 1)] > h[x]) { return -1; } int l = a; int r = b; while (l < r) { int mid = (l + r) >> 1; int pos = st.get(mid, b); if (h[pos] > h[x]) { l = mid + 1; } else { r = mid; } } int s = st.get(l, b); l = c; r = d; int val = h[st.get(s, c - 1)]; while (l < r) { int mid = (l + r) >> 1; int pos = st.get(c, mid); if (h[pos] > val) { r = mid; } else { l = mid + 1; } } int t = l; int ans = 0; for (int b = lg - 1; b >= 0; b--) { int ns = go_high[s][b]; if (h[ns] < h[t]) { s = ns; ans += (1 << b); } } if (c <= go_right[s][0] && go_right[s][0] <= d) { return ans + 1; } if (h[go_high[s][0]] < h[x]) { assert(go_high[s][0] < s); s = go_high[s][0]; // assert(s < c); // s = go_low[s][0]; // assert(c <= s && s <= d); return ans + 2; } assert(s < c); assert(h[s] < h[t]); assert(h[go_high[s][0]] > h[x]); for (int b = lg - 1; b >= 0; b--) { int ns = go_low[s][b]; if (h[ns] <= h[t]) { s = ns; ans += (1 << b); } } 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...