This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "jumps.h"
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
const int LOG = 18;
int N;
vector<int> H;
int jump_left[LOG][MAXN];
int jump_right[LOG][MAXN];
int jump_high[LOG][MAXN];
void init(int _N, std::vector<int> _H) {
    N = _N;
    H = _H;
    // Build first larger to the left
    stack<int> decreasing_h;
    for(int i = 0; i < N; i++){
        while(!decreasing_h.empty() && H[decreasing_h.top()] <= H[i])decreasing_h.pop();
        
        if(decreasing_h.empty())jump_left[0][i] = -1;
        else jump_left[0][i] = decreasing_h.top();
        decreasing_h.push(i);
    }
    
    while(!decreasing_h.empty())decreasing_h.pop();
    // Build first larger to the right
    for(int i = N - 1; i >= 0; --i){
        while(!decreasing_h.empty() && H[decreasing_h.top()] <= H[i])decreasing_h.pop();
        
        if(decreasing_h.empty())jump_right[0][i] = -1;
        else jump_right[0][i] = decreasing_h.top();
        decreasing_h.push(i);;
    }
    // Build jump to higher position
    for(int i = 0; i < N; i++){
        if(jump_left[0][i] == -1 && jump_right[0][i] == -1)jump_high[0][i] = -1;
        else if(jump_left[0][i] == -1)jump_high[0][i] = jump_right[0][i];
        else if(jump_right[0][i] == -1)jump_high[0][i] = jump_left[0][i];
        else {
            jump_high[0][i] = H[jump_left[0][i]] > H[jump_right[0][i]] ? jump_left[0][i] : jump_right[0][i];
        }
    }
    // Build sparse table
    for(int j = 1; j < LOG; j++){
        for(int i = 0; i < N; i++){
            jump_left[j][i] = jump_right[j][i] = jump_high[j][i] = -1;
            if(jump_left[j - 1][i] != -1){
                jump_left[j][i] = jump_left[j - 1][jump_left[j - 1][i]];
            }
            if(jump_right[j - 1][i] != -1){
                jump_right[j][i] = jump_right[j - 1][jump_right[j - 1][i]];
            }
            if(jump_high[j - 1][i] != -1){
                jump_high[j][i] = jump_high[j - 1][jump_high[j - 1][i]];
            }
            
        }
    }
}
int minimum_jumps(int A, int B, int C, int D) {
    int now = B;
    // Jump left as long as jump_right still <= D
    // and position to_left >= A
    for(int i = LOG - 1; i >= 0; --i){
        int to_left = jump_left[i][now];
        if(to_left != -1 && A <= to_left && 
                jump_right[0][to_left] <= D && jump_right[0][to_left] != -1){
            now = to_left;
        }
    }
    int jump = 0;
    // Jump to higher as long as jump_right still < C
    for(int i = LOG - 1; i >= 0; --i){
        int nx_pos = jump_high[i][now];
        if(nx_pos != -1 && jump_right[0][nx_pos] < C && jump_right[0][nx_pos] != -1){
            now = nx_pos;
            jump += (1 << i);
        }
    }
    for(int i = LOG - 1; i >= 0; --i){
        int to_right = jump_right[i][now];
        if(to_right != -1 && to_right < C){
            now = to_right;
            jump += (1 << i);
        }
    }
    if(jump_right[0][now] == -1 || jump_right[0][now] > D)return -1;
    return jump + 1;
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |