Submission #595704

#TimeUsernameProblemLanguageResultExecution timeMemory
595704OzyRainforest Jumps (APIO21_jumps)C++17
100 / 100
1415 ms97584 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,y;
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,0,n + 1) {
        while (cont > 0 && arr[pila.top()] < arr[i]) {pila.pop(); cont--;}

        if (cont == 0) vecinos[i].first = i;
        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,0) {
        while (cont > 0 && arr[pila.top()] < arr[i]) {pila.pop(); cont--;}

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

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

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

    vecinos[n + 1].first = izq[0][N + 1] = 0;
    vecinos[0].second = der[0][0] = N + 1;

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

    //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];
    }

    // AGREGADO:
    if (der[0][m] > D) return -1;

    // AGREGADO
    if (arr[B] > arr[m]){
        if (der[0][B] <= D) return 1;
        else return -1;
    }

    // crezco a la izquierda
    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;
    y = vecinos[x].second;
    if (x >= A && x <= B && y >= C && y <= D) return 1;
    else if (x < A && x > 0 && y >= C && y <= D) return res+2;

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

    if (der[0][act] <= D) return res + 1;
    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...