Submission #1201192

#TimeUsernameProblemLanguageResultExecution timeMemory
1201192browntoadRainforest Jumps (APIO21_jumps)C++20
100 / 100
488 ms77956 KiB
#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 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...