#include "jumps.h"
#include <bits/stdc++.h>
using namespace std;
#define ll long long
// #define int ll
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define REP1(i, n) FOR(i, 1, n+1)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#define pii pair<int, int>
#define f first
#define s second
#define pb push_back
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) (int)((x).size())
namespace{
const ll maxn = 2e5+5;
const ll mxpw = 19;
int smaxR[maxn][mxpw];
int smaxL[maxn][mxpw];
int jumpR[maxn][mxpw];
int ML[maxn][mxpw]; // where i jump to, most left
int MR[maxn][mxpw];
vector<int> h(maxn);
int n;
}
void init(int N, std::vector<int> H) {
n = N;
REP(i, n) h[i] = H[i];
REP(i, n){
smaxL[i][0] = H[i];
REP1(j, mxpw-1){
smaxL[i][j] = max(smaxL[i][j-1], smaxL[max(0, i-(1<<j-1))][j-1]);
}
}
RREP(i, n){
smaxR[i][0] = H[i];
REP1(j, mxpw-1){
smaxR[i][j] = max(smaxR[i][j-1], smaxR[min(n-1, i+(1<<j-1))][j-1]);
}
}
stack<int> st;
RREP(i, n){
while(SZ(st) && h[st.top()] < h[i]) st.pop();
if (!SZ(st)){
MR[i][0] = i; // itself
jumpR[i][0] = i;
}
else{
MR[i][0] = st.top();
jumpR[i][0] = st.top();
}
st.push(i);
}
while(SZ(st)) st.pop();
REP(i, n){
while(SZ(st) && h[st.top()] < h[i]) st.pop();
if (!SZ(st)){
ML[i][0] = i; // itself
}
else{
ML[i][0] = st.top();
}
st.push(i);
}
REP1(j, mxpw-1){
RREP(i, n){
MR[i][j] = max(MR[MR[i][j-1]][j-1], MR[ML[i][j-1]][j-1]);
jumpR[i][j] = jumpR[jumpR[i][j-1]][j-1];
}
REP(i, n){
ML[i][j] = min(ML[ML[i][j-1]][j-1], ML[MR[i][j-1]][j-1]);
}
}
}
int mxH(int l, int r){
if (l > r) return 0;
int p = 31-__builtin_clz(r-l+1);
return max(smaxR[l][p], smaxL[r][p]);
}
int minimum_jumps(int A, int B, int C, int D){
if (h[B] > mxH(C, D)) return -1;
if (mxH(B+1, C-1) > mxH(C, D)) return -1;
int mxCD = mxH(C, D);
int l = A, r = B;
while(l < r){
int mid = l+r>>1;
if (mxH(mid, B) < mxCD) r = mid;
else l = mid+1;
}
int tmp = mxH(l, B);
r = B;
while(l < r){
int mid = l+r+1>>1;
if (mxH(mid, B) == tmp) l = mid;
else r = mid-1;
}
int cnt = 1;
int curL = l, curR = l;
int cntbust = 0;
RREP(i, mxpw){
int tmpL = min(ML[curL][i], ML[curR][i]);
int tmpR = max(MR[curL][i], MR[curR][i]);
if (mxH(tmpL, tmpL) < mxCD){
cntbust += (1<<i);
curL = tmpL; curR = tmpR;
}
}
if (curR >= C){ // sometime before, already ok
curL = l; curR = l;
RREP(i, mxpw){
int tmpL = min(ML[curL][i], ML[curR][i]);
int tmpR = max(MR[curL][i], MR[curR][i]);
if (tmpR < C){
cnt += (1<<i);
curL = tmpL; curR = tmpR;
}
}
return cnt;
}
// else, a sequence jumping to left is a waste of time
cnt = cntbust+1;
curR = max(MR[curR][0], MR[curL][0]);
if (curR >= C) return cnt;
RREP(i, mxpw){
int tmpR = jumpR[curR][i];
if (tmpR < C){
curR = tmpR;
cnt += (1<<i);
}
}
cnt++;
return cnt;
}
/*
14 1
13 8 6 5 4 3 0 1 2 7 10 11 12 14
6 6 13 13
11 1
100 5 4 3 2 1 6 7 8 9 10
1 5 10 10
*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |