Submission #948421

#TimeUsernameProblemLanguageResultExecution timeMemory
948421Alihan_8밀림 점프 (APIO21_jumps)C++17
77 / 100
4061 ms63608 KiB
#include <bits/stdc++.h>

#include "jumps.h"

using namespace std;

#define all(x) x.begin(), x.end()
#define ar array
#define pb push_back
#define ln '\n'
//#define int long long

using i64 = long long;

template <class F, class _S>
bool chmin(F &u, const _S &v){
    bool flag = false;
    if ( u > v ){
        u = v; flag |= true;
    }
    return flag;
}

template <class F, class _S>
bool chmax(F &u, const _S &v){
    bool flag = false;
    if ( u < v ){
        u = v; flag |= true;
    }
    return flag;
}

const int N = 2e5 + 1;

vector <int> L, R, H;

vector <vector<int>> G, T, up(20), _up(20);

int n;

struct SegTree{
    int T[N * 4], id[N * 4];
    SegTree(){
        for ( int i = 0; i < N * 4; i++ ){
            T[i] = 0;
        }
    }
    void upd(int v, int l, int r, int pos, int val){
        if ( l == r ){
            T[v] = val;
            id[v] = l;
            return;
        }
        int md = (l + r) >> 1;
        if ( pos > md ){
            upd(v * 2 + 1, md + 1, r, pos, val);
        } else{
            upd(v * 2, l, md, pos, val);
        }
        T[v] = max(T[v * 2], T[v * 2 + 1]);
        if ( T[v] == T[v * 2] ){
            id[v] = id[v * 2];
        } else id[v] = id[v * 2 + 1];
    };
    void upd(int pos, int val){
        upd(1, 0, n - 1, pos, val);
    }
    pair <int,int> get(int v, int l, int r, int tl, int tr){
        pair <int,int> ret;
        ret = {-1, -1};
        if ( l > tr or r < tl ){
            return ret;
        }
        if ( tl <= l && tr >= r ){
            return {T[v], id[v]};
        }
        int md = (l + r) >> 1;
        return max(get(v * 2, l, md, tl, tr), get(v * 2 + 1, md + 1, r, tl, tr));
    }
    int get(int l, int r){
        return get(1, 0, n - 1, l, r).second;
    }
} seg;

int f(int u, int v){
    int ret = 0;
    for ( int i = 19; i >= 0; i-- ){
        if ( H[up[i][u]] <= H[v] ){
            ret += 1 << i;
            u = up[i][u];
        }
    }
    for ( int i = 19; i >= 0; i-- ){
        if ( H[_up[i][u]] <= H[v] ){
            ret += 1 << i;
            u = _up[i][u];
        }
    }
    if ( H[u] != H[v] ) ret = -1;
    return ret;
}

void init(int N, std::vector<int> H_) {
    n = N; H = H_;
    L.resize(n), R.resize(n);
    G.resize(n), T.resize(n);
    H.pb(n + 5);
    stack <int> stk;
    stk.push(-1);
    for ( int i = 0; i < n; i++ ){
        while ( stk.size() > 1 && H[stk.top()] <= H[i] ){
            stk.pop();
        } L[i] = stk.top();
        stk.push(i);
    }
    while ( stk.size() > 1 ) stk.pop();
    for ( int i = n - 1; i >= 0; i-- ){
        while ( stk.size() > 1 && H[stk.top()] <= H[i] ){
            stk.pop();
        } R[i] = stk.top();
        stk.push(i);
    }
    for ( int i = 0; i < n; i++ ){
        if ( L[i] == -1 && R[i] == -1 ){
            continue;
        }
        if ( L[i] == -1 || (R[i] != -1 && H[L[i]] < H[R[i]]) ){
            G[i].pb(R[i]);
        } else G[i].pb(L[i]);
        if ( L[i] != -1 ){
            T[i].pb(L[i]);
        }
        if ( R[i] != -1 ){
            T[i].pb(R[i]);
        }
    }
    for ( int i = 0; i < 20; i++ ){
        up[i].resize(n + 1, n);
        _up[i].resize(n + 1, n);
    }
    for ( int i = 0; i < n; i++ ){
        seg.upd(i, H[i]);
        if ( R[i] != -1 ){
            _up[0][i] = R[i];
        }
        if ( !G[i].empty() ){
            up[0][i] = G[i].back();
        }
    }
    for ( int i = 1; i < 20; i++ ){
        for ( int j = 0; j <= n; j++ ){
            up[i][j] = up[i - 1][up[i - 1][j]];
            _up[i][j] = _up[i - 1][_up[i - 1][j]];
        }
    }
}

int minimum_jumps(int A, int B, int C, int D) {
    if ( C == D ){
        int l = A, r = B, v = C;
        while ( l < r ){
            int md = (l + r) >> 1;
            if ( H[seg.get(md, B)] <= H[v] ){
                r = md;
            } else l = md + 1;
        }
        return f(seg.get(l, B), C);
    }

    vector <int> dp(n, n);
    queue <int> q;
    for ( int i = A; i <= B; i++ ){
        dp[i] = 0;
        q.push(i);
    }
    while ( !q.empty() ){
        int u = q.front();
        q.pop();
        for ( auto &v: T[u] ){
            if ( chmin(dp[v], dp[u] + 1) ){
                q.push(v);
            }
        }
    }
    int opt = n;
    for ( int i = C; i <= D; i++ ){
        chmin(opt, dp[i]);
    }
    if ( opt == n ) opt = -1;
    return opt;
}
#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...