#include "jumps.h"
#include<bits/stdc++.h>
using namespace std;
int n, h[200005], le[200005], ri[200005], jump_max[200005][20], jumpri[200005][20];
vector<int> st[800020];
inline bool cmp(const int x, const int y)
{
return h[x] < h[y];
}
void build(int node, int l, int r)
{
if(l == r) st[node].push_back(l);
else{
build(node*2, l, (l+r)/2);
build(node*2+1, (l+r)/2+1, r);
int j = 0;
for(int i = 0; i < st[node*2].size(); i++){
while(j < st[node*2+1].size() && h[st[node*2+1][j]] < h[st[node*2][i]]){
st[node].push_back(st[node*2+1][j]);
j++;
}
st[node].push_back(st[node*2][i]);
}
while(j < st[node*2+1].size()){
st[node].push_back(st[node*2+1][j]);
j++;
}
}
}
int query(int node, int l, int r, int tl, int tr, int val)
{
if(l > tr || r < tl) return -1;
if(l >= tl && r <= tr){
int p = lower_bound(st[node].begin(), st[node].end(), val, cmp) - st[node].begin();
if(p == 0) return -1;
else return st[node][p-1];
}
else{
int x = query(node*2, l, (l+r)/2, tl, tr, val);
int y = query(node*2+1, (l+r)/2+1, r, tl, tr, val);
if(x == -1) return y;
if(y == -1) return x;
if(h[x] < h[y]) return y;
else return x;
}
}
int query_atleast_right(int node, int l, int r, int tl, int tr, int val)
{
if(l > tr || r < tl) return -1;
if(l >= tl && r <= tr){
int p = lower_bound(st[node].begin(), st[node].end(), val, cmp) - st[node].begin();
if(p == st[node].size()) return -1;
else return st[node][p-1];
}
else{
int x = query_atleast_right(node*2, l, (l+r)/2, tl, tr, val);
int y = query_atleast_right(node*2+1, (l+r)/2+1, r, tl, tr, val);
if(y == -1) return x;
else return y;
}
}
void init(int N, vector<int> H) {
n = N;
for(int i = 0; i < n; i++) h[i+1] = H[i];
h[0] = h[n+1] = 1e9; ri[n+1] = n+1;
for(int i = 1; i <= n; i++){
le[i] = i-1;
while(h[le[i]] < h[i]) le[i] = le[le[i]];
}
for(int i = n; i >= 1; i--){
ri[i] = i+1;
while(h[ri[i]] < h[i]) ri[i] = ri[ri[i]];
}
for(int i = 1; i <= n; i++){
if(h[le[i]] > h[ri[i]]) jump_max[i][0] = le[i];
else jump_max[i][0] = ri[i];
jumpri[i][0] = ri[i];
}
jumpri[n+1][0] = jump_max[n+1][0] = n+1;
for(int j = 1; j <= 19; j++){
for(int i = 0; i <= n+1; i++){
jump_max[i][j] = jump_max[jump_max[i][j-1]][j-1];
jumpri[i][j] = jumpri[jumpri[i][j-1]][j-1];
}
}
build(1, 1, n);
}
int minimum_jumps(int l1, int r1, int l2, int r2) {
l1++; r1++; l2++; r2++;
//We have l2 = r2
//First check if it's possible
int p1 = query_atleast_right(1, 1, n, l1, r1, l2);
l1 = query(1, 1, n, max(p1+1, l1), r1, l2); //We greedily choose the largest node
if(l1 == -1) return -1;
int u = l1;
for(int i = 19; i >= 0; i--) if(jumpri[u][i] <= l2) u = jumpri[u][i];
if(u < l2) return -1;
//Now find the best answer
int ans = 0; u = l1;
for(int i = 19; i >= 0; i--) if(h[jump_max[u][i]] < h[l2]){
u = jump_max[u][i]; ans += (1 << i);
}
for(int i = 19; i >= 0; i--) if(jumpri[u][i] <= l2){
u = jumpri[u][i]; ans += (1 << i);
}
return ans;
}
| # | 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... |