제출 #595690

#제출 시각아이디문제언어결과실행 시간메모리
595690OzyRainforest Jumps (APIO21_jumps)C++17
0 / 100
32 ms18956 KiB
#include "jumps.h"
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for (int i = (a); i <= (b); i++)
#define repa(i,a,b) for (int i = (a); i >= (b); i--)
#define lli long long int
#define debug(a) cout << #a << " = " << a << endl
#define debugsl(a) cout << #a << " = " << a << ", "

#define MAX 200000

lli n,cont,m,act,res,x;
lli arr[MAX+2];
pair<lli,lli> vecinos[MAX+2];
stack<lli> pila;
//sparse
lli izq[20][MAX+2], der[20][MAX+2], bestway[20][MAX+2];

void init(int N, std::vector<int> H) {
    n = N;
    rep(i,0,n-1) arr[i+1] = H[i];
    arr[0] = arr[n + 1] = n + 1;

    cont = 0;
    while (!pila.empty()) pila.pop();
    rep(i,1,n) {
        while (cont > 0 && arr[pila.top()] < arr[i]) {pila.pop(); cont--;}

        if (cont == 0) vecinos[i].first = 0;
        else vecinos[i].first = pila.top();

        izq[0][i] = vecinos[i].first;

        pila.push(i);
        cont++;
    }

    cont = 0;
    while (!pila.empty()) pila.pop();
    repa(i,n,1) {
        while (cont > 0 && arr[pila.top()] < arr[i]) {pila.pop(); cont--;}

        if (cont == 0) vecinos[i].second = N + 1;
        else vecinos[i].second = pila.top();

        der[0][i] = vecinos[i].second;

        pila.push(i);
        cont++;
    }

    izq[0][0] = izq[0][N + 1] = 0;
    der[0][0] = der[0][N + 1] = N + 1;

    //bestway
    rep(i,1,n) {
        bestway[i][0] = (arr[ vecinos[i].first ] > arr[ vecinos[i].second ]) ? vecinos[i].first : vecinos[i].second;
    }

    //monotones
    rep(i,1,18) {
        rep(j,0,n+1) {
            izq[i][j] = izq[ i-1 ][ izq[i-1][j] ];
            der[i][j] = der[ i-1 ][ der[i-1][j] ];
            bestway[i][j] = bestway[ i-1 ][ bestway[i-1][j] ];
        }
    }

}

int minimum_jumps(int A, int B, int C, int D) {
    A++;
    B++;
    C++;
    D++;

    // no existe la m
    if (B == C-1) {
        act = vecinos[B].second;
        if (C <= act && act <= D) return 1;
        else return -1;
    }

    //calculo m
    m = B+1;
    repa(i,18,0) {
        if (der[i][m] >= C) continue;
        m = der[i][m];
    }

    // crezco a la derecha
    act = B;
    repa(i,18,0) {
        if (izq[i][act] < A) continue;
        if (arr[izq[i][act]] < arr[m]) act = izq[i][act];
    }

    // crezco el bestway
    res = 0;

    repa(i,18,0) {
        if (arr[bestway[i][act]] < arr[m]) {
            act = bestway[i][act];
            res += (1<<i);
        }
    }

    //checo izq
    x = vecinos[act].first;
    x = vecinos[x].second;
    if (x >= C && x <= D) return res+2;

    //crezco a la derecha
    repa(i,18,0) {
        if (der[i][act] > D) continue;
        act = der[i][act];
        res += (1 << i);
        if (act >= C) return res;
    }

    return -1;
}
#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...