Submission #553945

#TimeUsernameProblemLanguageResultExecution timeMemory
553945Jarif_RahmanRainforest Jumps (APIO21_jumps)C++17
100 / 100
1248 ms74784 KiB
#include <bits/stdc++.h> #define pb push_back #define f first #define sc second using namespace std; typedef long long int ll; typedef string str; struct sparse_table{ vector<int> lg; vector<vector<pair<int, int>>> v; sparse_table(vector<int> _v){ int n = _v.size(); lg.resize(n+1); for(int i = 0; i <= n; i++) lg[i] = log2(i); int k = 0, p = 1; while(p < n) p*=2, k++; k++; v = vector<vector<pair<int, int>>>(n, vector<pair<int, int>>(k, make_pair(0, 0))); for(int i = 0; i < n; i++) v[i][0] = {_v[i], i}; for(int p = 1; p < k; p++){ for(int i = 0; i < n; i++){ v[i][p] = max(v[i][p], v[i][p-1]); if(i + (1<<(p-1)) < n) v[i][p] = max(v[i][p], v[i + (1<<(p-1))][p-1]); } } } pair<int, int> query(int a, int b){ int p = lg[b-a+1]; return max(v[a][p], v[b-(1<<p)+1][p]); } }; const int K = 21; const int inf = 1e9; int n; vector<int> h; vector<int> jump[2]; vector<int> anc[2][K]; sparse_table sp({}); template<int k> int get_anc(int nd, int h){ for(int i = 0; i < K; i++){ if(h%2 == 1) nd = anc[k][i][nd]; h/=2; } return nd; } template<int k> int binlift(int nd, int l){ if(h[nd] >= l) return 0; for(int i = K-1; i >= 0; i--) if(h[anc[k][i][nd]] <= l) return binlift<k>(anc[k][i][nd], l)+(1<<i); return 0; } void init(int N, vector<int> H){ for(int &x: H) x--; n = N, h = H; h.pb(n); fill(jump, jump+2, vector<int>(n, n)); fill(anc[0], anc[0]+K, vector<int>(n+1, n)); fill(anc[1], anc[1]+K, vector<int>(n+1, n)); sp = sparse_table(H); stack<int> st; for(int i = n-1; i >= 0; i--){ while(!st.empty() && h[i] > h[st.top()]){ jump[0][st.top()] = i; st.pop(); } st.push(i); } while(!st.empty()) st.pop(); for(int i = 0; i < n; i++){ while(!st.empty() && h[i] > h[st.top()]){ jump[1][st.top()] = i; st.pop(); } st.push(i); } while(!st.empty()) st.pop(); for(int i = 0; i < n; i++){ anc[0][0][i] = h[jump[0][i]] < h[jump[1][i]] ? jump[0][i] : jump[1][i]; anc[1][0][i] = h[jump[0][i]] > h[jump[1][i]] ? jump[0][i] : jump[1][i]; if(anc[1][0][i] == n) anc[1][0][i] = anc[0][0][i]; } for(int p = 1; p < K; p++) for(int i = 0; i <= n; i++) anc[0][p][i] = anc[0][p-1][anc[0][p-1][i]], anc[1][p][i] = anc[1][p-1][anc[1][p-1][i]]; } int minimum_jumps(int A, int B, int C, int D){ int l = 1, r = B-A+1; int m1 = 0, m2 = sp.query(C, D).f; if(B+1 < C) m1 = sp.query(B+1, C-1).f; if(m1 > m2) return -1; while(l < r){ int md = (l+r)/2; if(sp.query(B-md+1, B).f > m2) r = md; else l = md+1; } int S = A; if(sp.query(B-l+1, B).f > m2){ S = B-l+2; if(S > B) return -1; } S = sp.query(S, B).sc; int ans = binlift<1>(S, m1); int nd = get_anc<1>(S, ans); if(h[nd] >= m1 && h[nd] <= m2) return ans+1; if(h[anc[1][0][nd]] <= m2) return ans+2; int x = binlift<0>(nd, m1); nd = get_anc<0>(nd, x); ans+=x; if(h[nd] >= m1 && h[nd] <= m2) return ans+1; if(h[anc[1][0][nd]] <= m2) return ans+2; 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...