Submission #718452

#TimeUsernameProblemLanguageResultExecution timeMemory
718452aryan12Rainforest Jumps (APIO21_jumps)C++17
48 / 100
1331 ms36120 KiB
#include "jumps.h" #include <bits/stdc++.h> #include <vector> using namespace std; const int MAXN = 2e5 + 5; int dp_min[19][MAXN], dp_max[19][MAXN]; int seg[MAXN * 4]; // at position i stores the value H[i] vector<int> H, REV; int N; void Build(int left, int right, int pos) { if(left == right) { seg[pos] = H[left]; return; } int mid = (left + right) / 2; Build(left, mid, pos * 2); Build(mid + 1, right, pos * 2 + 1); seg[pos] = max(seg[pos * 2], seg[pos * 2 + 1]); } int Query(int l, int r, int pos, int ql, int qr) { if(ql <= l && r <= qr) { return seg[pos]; } if(ql > r || l > qr) { return -1; } int mid = (l + r) >> 1; return max(Query(l, mid, pos * 2, ql, qr), Query(mid + 1, r, pos * 2 + 1, ql, qr)); } pair<int, int> Query(int l, int r, int pos, int ql, int qr, int qval) { // first is the smallest accessible element // second is whether the range has become inaccessible or not? if(ql > r || l > qr) { // cout << "(" << l << ", " << r << ") returns: {" << 0 << ", " << 0 << "}\n"; return {-1, 0}; } if(ql <= l && r <= qr && seg[pos] <= qval) { // cout << "(" << l << ", " << r << ") returns: {" << seg[pos] << ", " << seg[pos] << "}\n"; return {seg[pos], seg[pos]}; } if(l == r && seg[pos] > qval) { // cout << "(" << l << ", " << r << ") returns: {" << -1 << ", " << -1 << "}\n"; return {-1, -1}; } int mid = (l + r) / 2; pair<int, int> ans1 = Query(mid + 1, r, pos * 2 + 1, ql, qr, qval); if(ans1.second == -1) { // cout << "(" << l << ", " << r << ") returns: {" << ans1.first << ", " << ans1.second << "}\n"; return ans1; } pair<int, int> ans2 = Query(l, mid, pos * 2, ql, qr, qval); if(ans2.second == -1) { // cout << "(" << l << ", " << r << ") returns: {" << max(ans1.first, ans2.first) << ", " << -1 << "}\n"; return {max(ans1.first, ans2.first), -1}; } // cout << "(" << l << ", " << r << ") returns: {" << max(ans1.first, ans2.first) << ", " << max(ans1.second, ans2.second) << "}\n"; return {max(ans1.first, ans2.first), max(ans1.second, ans2.second)}; } void init(int n, std::vector<int> h) { stack<int> s; N = n; REV.resize(N + 1); for(int i = 0; i < h.size(); i++) { H.push_back(h[i]); REV[H[i]] = i; } Build(0, N - 1, 1); for(int i = 0; i < N; i++) { while(!s.empty() && H[s.top()] < H[i]) { s.pop(); } if(s.empty()) { dp_min[0][i] = -1; } else { dp_min[0][i] = s.top(); } s.push(i); } while(!s.empty()) { s.pop(); } for(int i = N - 1; i >= 0; i--) { while(!s.empty() && H[s.top()] < H[i]) { s.pop(); } if(s.empty()) { dp_max[0][i] = -1; } else { dp_max[0][i] = s.top(); } s.push(i); if(dp_min[0][i] == -1 || (dp_max[0][i] != -1 && H[dp_max[0][i]] < H[dp_min[0][i]])) { swap(dp_min[0][i], dp_max[0][i]); } } for(int i = 1; i < 19; i++) { for(int j = 0; j < N; j++) { dp_min[i][j] = (dp_min[i - 1][j] == -1) ? -1 : dp_min[i - 1][dp_min[i - 1][j]]; dp_max[i][j] = (dp_max[i - 1][j] == -1) ? -1 : dp_max[i - 1][dp_max[i - 1][j]]; assert(dp_max[i][j] == -1 || H[dp_max[i][j]] >= H[dp_min[i][j]]); } } // for(int i = 0; i < N; i++) // { // for(int j = 0; j < 19; j++) // { // cout << "val: " << min_max_node[j][i] << ", " << max_max_node[j][i] << "\n"; // cout << "dp: " << dp_min[j][i] << ", " << dp_max[j][i] << "\n"; // } // } } int query(int l, int r, int pos, int ql, int qr, int qval) { if(ql > r || l > qr || seg[pos] <= qval) { return -1; } if(l == r) { return l; } int mid = (l + r) >> 1; int ans1 = query(l, mid, pos * 2, ql, qr, qval); if(ans1 != -1) { return ans1; } return query(mid + 1, r, pos * 2 + 1, ql, qr, qval); } int minimum_jumps(int A, int B, int C, int D) { // A = B && C = D // cout << "---- ---- ---- ---- ----\n"; // cout << "A = " << A << ", B = " << B << "\n"; int HIGHEST = Query(0, N - 1, 1, C, D); HIGHEST = REV[HIGHEST]; // cout << "HIGHEST = " << HIGHEST << "\n"; int query_result = Query(0, N - 1, 1, A, B, H[HIGHEST]).first; // cout << "query_result = " << query_result << "\n"; if(query_result == -1) { return -1; } A = REV[query_result]; B = A; // cout << "A = " << A << "\n"; C = query(0, N - 1, 1, C, D, H[A]); // query for the smallest element >= H[A] // cout << "C = " << C << "\n"; if(C == -1) { return -1; } // C = REV[C]; D = C; // cout << "A = " << A << ", B = " << B << "\n"; // cout << "---- ---- ---- ---- ----\n"; int ans = 0; for(int i = 18; i >= 0; i--) { if(dp_max[i][A] != -1 && H[dp_max[i][A]] <= H[C]) { ans += (1 << i); A = dp_max[i][A]; } } // cout << "ans = " << ans << ", A = " << A << "\n"; for(int i = 18; i >= 0; i--) { if(dp_min[i][A] != -1 && H[dp_min[i][A]] <= H[C]) { ans += (1 << i); A = dp_min[i][A]; } } // cout << "ans = " << ans << ", A = " << A << "\n"; if(A == C) { return ans; } return -1; }

Compilation message (stderr)

jumps.cpp: In function 'void init(int, std::vector<int>)':
jumps.cpp:80:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   80 |     for(int i = 0; i < h.size(); i++)
      |                    ~~^~~~~~~~~~
#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...