Submission #678936

#TimeUsernameProblemLanguageResultExecution timeMemory
678936cig32Rainforest Jumps (APIO21_jumps)C++17
100 / 100
1483 ms53796 KiB
#include "jumps.h" #include <stack> #include <vector> #include <iostream> #include <queue> const int MAXN = 200010; int L[MAXN], R[MAXN]; int N_; int mi[19][MAXN], ma[19][MAXN], rr[19][MAXN]; bool st1; int V[MAXN]; std::pair<int, int> str[4 * MAXN]; void u(int l, int r, int tar, int idx, int val) { if(l == r) { str[idx] = {val, tar}; return; } int mid = (l + r) >> 1; if(tar <= mid) u(l, mid, tar, 2*idx+1, val); else u(mid+1, r, tar, 2*idx+2, val); str[idx] = max(str[2*idx+1], str[2*idx+2]); } std::pair<int, int> qu1(int l, int r, int constl, int constr, int idx) { if(l<=constl && constr<=r) return str[idx]; int mid = (constl+constr) >> 1; if(mid < l || r < constl) return qu1(l, r, mid+1, constr, 2*idx+2); else if(constr < l || r < mid+1) return qu1(l, r, constl, mid, 2*idx+1); else return max(qu1(l, r, constl, mid, 2*idx+1), qu1(l, r, mid+1, constr, 2*idx+2)); } int qu2(int l, int r, int constl, int constr, int idx, int val) { if(l<=constl && constr<=r) { if(str[idx].first <= val) { return -1; } while(constl < constr) { int mid = (constl + constr) >> 1; if(str[2*idx+2].first > val) constl = mid + 1, idx = 2 * idx + 2; else constr = mid, idx = 2 * idx + 1; } return constl; } int mid = (constl+constr) >> 1; if(mid<l || r< constl) return qu2(l, r, mid+1, constr, 2*idx+2, val); else if(constr< l || r< mid+1) return qu2(l, r, constl, mid, 2*idx+1, val); else { int res = qu2(l, r, mid+1, constr, 2*idx+2, val); if(res != -1) return res; return qu2(l, r, constl, mid, 2*idx+1, val); } } void update(int i, int v) { u(0, N_ - 1, i, 0, v); } int query_max(int l, int r) { return qu1(l, r, 0, N_ - 1, 0).second; } int last_greater(int l, int r, int c) { return qu2(l, r, 0, N_ - 1, 0, c); } void init(int N, std::vector<int> H) { N_ = N; for(int i=0; i<N; i++) update(i, H[i]); st1 = 1; for(int i=0; i<N; i++) { L[i] = R[i] = -1; V[i] = H[i]; if(H[i] != i + 1) st1 = 0; } std::stack<int> st; for(int i=0; i<N; i++) { while(st.size() && H[st.top()] < H[i]) { st.pop(); } if(st.size()) L[i] = st.top(); st.push(i); } while(st.size()) st.pop(); for(int i=N-1; i>=0; i--) { while(st.size() && H[st.top()] < H[i]) { st.pop(); } if(st.size()) R[i] = st.top(); st.push(i); } while(st.size()) st.pop(); for(int i=0; i<N; i++) { rr[0][i] = R[i]; } for(int i=0; i<N; i++) { if(L[i] == -1 && R[i] == -1) { mi[0][i] = ma[0][i] = -1; } else if(L[i] == -1) { mi[0][i] = ma[0][i] = R[i]; } else if(R[i] == -1) { mi[0][i] = ma[0][i] = L[i]; } else { mi[0][i] = (H[L[i]] < H[R[i]] ? L[i] : R[i]); ma[0][i] = (H[L[i]] > H[R[i]] ? L[i] : R[i]); } } for(int i=1; i<19; i++) { for(int j=0; j<N; j++) { if(mi[i-1][j] == -1) mi[i][j] = -1; else mi[i][j] = mi[i-1][mi[i-1][j]]; if(ma[i-1][j] == -1) ma[i][j] = -1; else ma[i][j] = ma[i-1][ma[i-1][j]]; if(rr[i-1][j] == -1) rr[i][j] = -1; else rr[i][j] = rr[i-1][rr[i-1][j]]; } } } int qcnt = 0; int minimum_jumps(int A, int B, int C, int D) { if(V[query_max(B, C - 1)] > V[query_max(C, D)]) return -1; int lg = last_greater(A, B, V[query_max(C, D)]); if(lg == -1) lg = A - 1; A = query_max(lg+1, B); //std::cout << A << " !!! "; int X = V[query_max(B, C - 1)]; int Y = V[query_max(C, D)]; int ans = 0; //std::cout << X << " " << Y << " "; for(int i=18; i>=0; i--) { if(ma[i][A] != -1) { if(V[ma[i][A]] < X) { ans += (1 << i); A = ma[i][A]; } } } if(C <= rr[0][A] && rr[0][A] <= D) return ans + 1; if(ma[0][A] != -1 && X <= V[ma[0][A]] && V[ma[0][A]] < Y) { return ans + 2; } int lb = 0, rb = (1 << 19) - 1; while(lb < rb) { int mid = (lb + rb) >> 1; bool ok = 1; int sto = A; for(int i=18; i>=0; i--) { if(!(mid & (1 << i))) continue; if(rr[i][sto] != -1) { if(V[rr[i][sto]] <= Y) { sto = rr[i][sto]; } } else { ok = 0; break; } } //std::cout << "Steps " << mid << " res " << sto << " flag " << ok << "\n"; if(C <= sto || !ok)rb = mid; else lb = mid+ 1; } if(rb != (1 << 19) - 1) return ans+ lb; return -1; }
#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...