Submission #654722

#TimeUsernameProblemLanguageResultExecution timeMemory
654722Sam_a17Rainforest Jumps (APIO21_jumps)C++14
56 / 100
4048 ms58096 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) { 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) { if(A == B && C == D) { int maxim = seg.qry(A, D); if(maxim >= h[D]) { return -1; } int ina = 0, inb = maxN, answ = 0; while(ina <= inb) { int mid = (ina + inb) / 2; int pos = get_mx(mid, A); if(h[pos] >= maxim) { answ = mid; inb = mid - 1; } else { ina = mid + 1; } } int pos = get_mx(answ, A); if(pos == D) return answ; if(h[pos] >= h[D]) { answ--; } pos = get_mx(answ, A); ina = 0, inb = maxN; int answ2 = 0; while(ina <= inb) { int mid = (ina + inb) / 2; int pos2 = get_r(mid, pos); if(h[pos2] >= h[D]) { answ2 = mid; inb = mid - 1; } else { ina = mid + 1; } } pos = get_r(answ2, pos); return answ2 + answ; } else { queue<pair<int, int>> q; vector<bool> vis(n + 1); for(int i = A; i <= B; i++) { q.push({i, 0}); vis[i] = true; } while(!q.empty()) { auto u = q.front(); q.pop(); if(u.first >= C && u.first <= D) { return u.second; } if(nxt[u.first][0] != -1 && !vis[nxt[u.first][0]]) { vis[nxt[u.first][0]] = true; q.push({nxt[u.first][0], u.second + 1}); } if(pre[u.first][0] != -1 && !vis[pre[u.first][0]]) { vis[pre[u.first][0]] = true; q.push({pre[u.first][0], u.second + 1}); } } 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...