Submission #1336162

#TimeUsernameProblemLanguageResultExecution timeMemory
1336162LIARainforest Jumps (APIO21_jumps)C++17
100 / 100
644 ms128808 KiB
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define v vector
#define lp(i, s, e) for (ll i = s; i < e; ++i)

ll n;
const ll inf = 1e18;
v<ll> h;
ll l[200005], r[200005], bl1[20][200005], bl2[20][200005], bl3[20][200005],
    fj[20][200005];

ll get(ll l, ll r) {
  ll lg = log2(r - l + 1);
  ll a = fj[lg][l];
  ll b = fj[lg][r - (1LL << lg) + 1];
  return h[a] > h[b] ? a : b;
}

void init(int N, std::vector<int> H) {
  n = N;
  lp(i, 0, n) h.push_back(H[i]);
  h.push_back(inf);
  lp(i, 0, n) fj[0][i] = i;
  lp(j, 1, 20) {
    lp(i, 0, n - (1 << j) + 1) {
      ll a = fj[j - 1][i];
      ll b = fj[j - 1][i + (1 << (j - 1))];
      fj[j][i] = h[a] > h[b] ? a : b;
    }
  }

  v<ll> st;
  lp(i, 0, n) {
    while (!st.empty() && h[st.back()] < h[i])
      st.pop_back();
    l[i] = st.empty() ? n : st.back();
    st.push_back(i);
  }
  st.clear();
  for (ll i = n - 1; i >= 0; --i) {
    while (!st.empty() && h[st.back()] < h[i])
      st.pop_back();
    r[i] = st.empty() ? n : st.back();
    st.push_back(i);
  }

  lp(i, 0, n) {
    bl2[0][i] = r[i];
    bl3[0][i] = l[i];
    ll mx = n;
    if (l[i] != n && r[i] != n)
      mx = h[l[i]] > h[r[i]] ? l[i] : r[i];
    else if (l[i] != n)
      mx = l[i];
    else if (r[i] != n)
      mx = r[i];
    bl1[0][i] = mx;
  }
  bl1[0][n] = bl2[0][n] = bl3[0][n] = n;

  lp(j, 1, 20) {
    lp(i, 0, n + 1) {
      bl1[j][i] = bl1[j - 1][bl1[j - 1][i]];
      bl2[j][i] = bl2[j - 1][bl2[j - 1][i]];
      bl3[j][i] = bl3[j - 1][bl3[j - 1][i]];
    }
  }
}

int minimum_jumps(int A, int B, int C, int D) {
  ll X = get(C, D), Y = get(B, C - 1);
  if (h[Y] > h[X])
    return -1;
  ll cur = B;
  for (ll j = 19; j >= 0; --j) {
    ll nxt = bl3[j][cur];
    if (nxt != n && nxt >= A && h[nxt] < h[X]) {
      cur = nxt;
    }
  }

  ll ans = 0;
  for (ll j = 19; j >= 0; --j) {
    ll nxt = bl1[j][cur];
    if (nxt != n && h[nxt] < h[X] && bl2[0][nxt] < C) {
      cur = nxt;
      ans += (1LL << j);
    }
  }
  if (bl1[0][cur] == bl3[0][cur] && bl1[0][cur] != n && h[bl1[0][cur]] < h[X] &&
      bl2[0][cur] < C) {
    cur = bl1[0][cur];
    ans++;
  }

  for (ll j = 19; j >= 0; --j) {
    ll nxt = bl2[j][cur];
    if (nxt != n && nxt < C) {
      cur = nxt;
      ans += (1LL << j);
    }
  }

  return ans + 1;
}

#ifndef EVAL
int main() {
  int N, Q;
  assert(2 == scanf("%d %d", &N, &Q));
  std::vector<int> H(N);
  for (int i = 0; i < N; ++i) {
    assert(1 == scanf("%d", &H[i]));
  }
  init(N, H);

  for (int i = 0; i < Q; ++i) {
    int A, B, C, D;
    assert(4 == scanf("%d %d %d %d", &A, &B, &C, &D));
    printf("%d\n", minimum_jumps(A, B, C, D));
  }
  return 0;
}
#endif
#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...