제출 #948421

#제출 시각아이디문제언어결과실행 시간메모리
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...