제출 #981564

#제출 시각아이디문제언어결과실행 시간메모리
981564Ghulam_Junaid밀림 점프 (APIO21_jumps)C++17
33 / 100
4051 ms570484 KiB
#include <bits/stdc++.h> #include "jumps.h" using namespace std; const int MXN = 2e5 + 10; const int T = 330; int n, pos[MXN], to_left[MXN], to_right[MXN], dp_left[MXN][T + 1], dp_right[MXN][T + 1]; vector<int> seg[4 * MXN], h; void build(int v = 1, int s = 0, int e = n){ if (e - s == 1){ seg[v] = {h[s]}; return; } int mid = (s + e) / 2, lc = 2 * v, rc = lc + 1; build(lc, s, mid); build(rc, mid, e); seg[v] = seg[lc]; for (int x : seg[rc]) seg[v].push_back(x); sort(seg[v].begin(), seg[v].end()); } int get(int l, int r, int x, int v = 1, int s = 0, int e = n){ // int mx = -1; // for (int i = l; i < r; i ++) // if (h[i] < x) // mx = max(mx, h[i]); // return mx; if (e <= l || r <= s) return -1; if (l <= s && e <= r){ if (x > seg[v].back()) return seg[v].back(); if (x <= seg[v][0]) return -1; int lb = lower_bound(seg[v].begin(), seg[v].end(), x) - seg[v].begin(); return seg[v][lb - 1]; } int mid = (s + e) / 2, lc = 2 * v, rc = lc + 1; return max(get(l, r, x, lc, s, mid), get(l, r, x, rc, mid, e)); } void init(int N, vector<int> H) { n = N; h = H; for (int i = 0; i < n; i ++) pos[h[i]] = i; build(); stack<int> S; for (int i = 0; i < n; i ++){ while(S.size() and h[S.top()] <= h[i]) S.pop(); if (S.size()) to_left[i] = S.top(); else to_left[i] = i; S.push(i); } while (S.size()) S.pop(); for (int i = n - 1; i >= 0; i --){ while (S.size() and h[S.top()] <= h[i]) S.pop(); if (S.size()) to_right[i] = S.top(); else to_right[i] = i; S.push(i); } // for (int i = 0; i < n; i ++){ // to_left[i] = to_right[i] = i; // for (int j = i + 1; j < n; j ++){ // if (h[j] > h[i]){ // to_right[i] = j; // break; // } // } // for (int j = i - 1; j >= 0; j --){ // if (h[j] > h[i]){ // to_left[i] = j; // break; // } // } // } for (int i = 0; i < n; i ++){ dp_left[i][1] = to_left[i]; dp_right[i][1] = to_right[i]; } for (int j = 2; j <= T; j ++){ for (int i = 0; i < n; i ++){ dp_left[i][j] = min(to_left[dp_left[i][j - 1]], to_left[dp_right[i][j - 1]]); dp_right[i][j] = max(to_right[dp_left[i][j - 1]], to_right[dp_right[i][j - 1]]); } } } int minimum_jumps(int A, int B, int C, int D) { B++, D++; int mx = get(C, D, n + 1); int l = A - 1, r = B - 1; if (get(r, C, n + 1) > mx) return -1; while (r - l > 1){ int mid = (l + r) / 2; if (get(mid, C, n + 1) > mx) l = mid; else r = mid; } int val = get(r, B, mx); if (val == -1) return -1; int st = pos[val]; if (get(st, C, n + 1) > mx) return -1; int ope = 0; if (C == D){ while (st < C){ if (h[dp_left[st][T]] < h[C] and h[dp_right[st][T]] < h[C]){ if (h[dp_left[st][T]] > h[dp_right[st][T]]) st = dp_left[st][T]; else st = dp_right[st][T]; ope += T; } else{ for (int i = 1; i < T; i ++){ if (h[dp_left[st][T - i]] < h[C] and h[dp_right[st][T - i]] < h[C]){ ope += T - i + 1; break; } } break; } } } else{ while (st < C){ ope++; int opt1 = to_left[st]; int opt2 = to_right[st]; if (opt2 >= C or h[opt2] > h[opt1] or h[opt1] > mx) st = opt2; else st = opt1; } } return ope; }
#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...