Submission #1282188

#TimeUsernameProblemLanguageResultExecution timeMemory
1282188khanhphucscratchRainforest Jumps (APIO21_jumps)C++20
0 / 100
38 ms28356 KiB
#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[200005];
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;
    }
}
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
    l1 = query(1, 1, n, l1, r1, l2); //We greedily choose the largest node
    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 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...