제출 #654710

#제출 시각아이디문제언어결과실행 시간메모리
654710Sam_a17밀림 점프 (APIO21_jumps)C++14
0 / 100
4024 ms46664 KiB
#include <bits/stdc++.h> using namespace std; #define dbg(x) cerr << #x << " " << x << endl; const int maxN = 2e5 + 10, LOG = 22, inf = 1e8; int h[maxN], n, pre[maxN][LOG], nxt[maxN][LOG]; int mx[maxN][LOG]; struct SegTree { vector<int> tree; int size = 1; void init(int s) { while(size < s) { size *= 2; } tree.assign(2 * size - 1, 0); } void upd(int u, int val, int x, int lx, int rx) { if(rx - lx == 1) { // dbg(val) tree[x] = val; return; } int mid = (lx + rx) / 2; if(u < mid) { upd(u, val, 2 * x + 1, lx, mid); } else { upd(u, val, 2 * x + 2, mid, rx); } tree[x] = max(tree[2 * x + 1], tree[2 * x + 2]); } void upd(int u, int val) { upd(u, val, 0, 0, size); } int qry(int l, int r, int x, int lx, int rx) { if(lx >= r || rx <= l) { return 0; } if(lx >= l && rx <= r) { // dbg(tree[x]) return tree[x]; } int mid = (lx + rx) / 2; int s1 = qry(l, r, 2 * x + 1, lx, mid); int s2 = qry(l, r, 2 * x + 2, mid, rx); return max(s1, s2); } int qry(int l, int r) { return qry(l, r, 0, 0, size); } }; SegTree seg; void init(int N, std::vector<int> H) { n = N, seg.init(n + 1); for(int i = 0; i < N; i++) { h[i] = H[i]; seg.upd(i, h[i]); // nxt[i][0] = pre[i][0] = i; } stack<pair<int, int>> st; for(int i = 0; i < N; i++) { while(!st.empty() && h[i] > st.top().first) { nxt[st.top().second][0] = i; st.pop(); } st.push({h[i], i}); } while(!st.empty()) st.pop(); for(int i = N - 1; i >= 0; i--) { while(!st.empty() && h[i] > st.top().first) { pre[st.top().second][0] = i; st.pop(); } st.push({h[i], i}); } for(int i = 0; i < N; i++) { if(h[nxt[i][0]] >= h[pre[i][0]]) { mx[i][0] = nxt[i][0]; } else { mx[i][0] = pre[i][0]; } } for(int j = 1; j < LOG; j++) { for(int i = 0; i < N; i++) { mx[i][j] = mx[mx[i][j - 1]][j - 1]; nxt[i][j] = nxt[nxt[i][j - 1]][j - 1]; pre[i][j] = pre[pre[i][j - 1]][j - 1]; } } } int get_mx(int mid, int node) { for(int i = 0; i < LOG; i++) { if(mid & (1 << i)) { node = mx[node][i]; } } return node; } int get_r(int mid, int node) { for(int i = 0; i < LOG; i++) { if(mid & (1 << i)) { node = nxt[node][i]; } } return node; } int minimum_jumps(int A, int B, int C, int D) { int maxim = seg.qry(A, D); if(maxim >= h[D]) { return -1; } int ina = 0, inb = 2, answ = 0; while(ina <= inb) { int mid = (ina + inb) / 2; int pos = get_mx(mid, A); if(h[pos] >= maxim) { if(h[pos] < h[D]) { answ = mid; } inb = mid - 1; } else { ina = mid + 1; } } int pos = get_mx(answ, A); if(pos == D) { return answ; } while(pos != D) { pos = nxt[pos][0]; answ++; } return answ; }
#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...