Submission #1362409

#TimeUsernameProblemLanguageResultExecution timeMemory
1362409AMel0nRainforest Jumps (APIO21_jumps)C++20
44 / 100
645 ms37532 KiB
#include "jumps.h"
#include <bits/stdc++.h>
using namespace std;
const int INF = 2e9 + 67;
const int MAXN = 2e5 + 5;
const int MAXLOG = 19;

int N;
vector<int> H, tree;
vector<vector<int>> jR, jM;

int ret(int l, int r) {
    if (min(l, r) == -1) return max(l, r);
    return (H[l] > H[r] ? l : r);
}
void build(int tl = 0, int tr = N-1, int i = 1) {
    if (tl == tr) {
        tree[i] = tl;
        return ;
    }
    int tm = (tl + tr) / 2;
    build(tl, tm, i * 2);
    build(tm + 1, tr, i * 2 + 1);
    tree[i] = ret(tree[i * 2], tree[i * 2 + 1]);
}
int query(int l, int r, int tl = 0, int tr = N-1, int i = 1) {
    if (l > r) return -1;
    if (tl == l && tr == r) return tree[i];
    int tm = (tl + tr) / 2;
    return ret(query(l, min(r, tm), tl, tm, i * 2), query(max(l, tm + 1), r, tm + 1, tr, i * 2 + 1));
}

void init(int N, vector<int> H) {
    ::N = N, ::H = H;
    tree.resize(N*4), jR.resize(MAXLOG, vector<int>(N)), jM.resize(MAXLOG, vector<int>(N));
    vector<int> stk;
    for(int i = N-1; i >= 0; i--) {
        while(stk.size() && H[stk.back()] < H[i]) stk.pop_back();
        jM[0][i] = (stk.size() ? stk.back() : i);
        jR[0][i] = (stk.size() ? stk.back() : i);
        stk.push_back(i);
    }
    while(stk.size()) stk.pop_back();
    for(int i = 0; i < N; i++) {
        while(stk.size() && H[stk.back()] < H[i]) stk.pop_back();
        if (stk.size() && H[stk.back()] > H[jM[0][i]]) jM[0][i] = stk.back();
        stk.push_back(i);
    }
    for(int j = 1; j < MAXLOG; j++) {
        for(int i = 0; i < N; i++) {
            jM[j][i] = jM[j-1][jM[j-1][i]];
            jR[j][i] = jR[j-1][jR[j-1][i]];
        }
    }
    build();
}
int find(int A, int B, int X) { // leftmost i such that H[max{i, B}] < H[E]
    int l = A, r = B+1;
    while(l < r) {
        int m = (l + r) / 2;
        if (H[query(m, B)] < H[X]) r = m;
        else l = m + 1;
    }
    return l;
}
int liftright(int S, int C, int D) {
    int res = 0, j = MAXLOG - 1;
    while(j >= 0) {
        if (jR[j][S] < C) {
            S = jR[j][S];
            res += (1 << j);
        }
        j--;
    }
    return (C <= jR[0][S] && jR[0][S] <= D ? res+1 : INF); 
}
int minimum_jumps(int A, int B, int C, int D) {
    int E = query(C, D), T = query(B, C);
    if (T > E) return -1;
    int le = find(A, B, E);
    if (le == B+1) return -1;
    int S = query(le, B);
    if (S == -1) return -1;

    int res = 0, j = MAXLOG - 1;
    while(j >= 0) {
        if (H[jM[j][S]] < H[E]) {
            S = jM[j][S];
            res += (1 << j);
        }
        j--;
    }
    res += liftright(S, C, D);
    return res < INF ? res : -1;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...