Submission #1282196

#TimeUsernameProblemLanguageResultExecution timeMemory
1282196khanhphucscratchRainforest Jumps (APIO21_jumps)C++20
27 / 100
546 ms75452 KiB
#include "jumps.h" #include<bits/stdc++.h> using namespace std; int n, h[200005], le[200005], ri[200005], jump_max[200005][20], jumpri[200005][20]; vector<int> st[800020]; inline bool cmp(const int x, const int y) { return h[x] < h[y]; } void build(int node, int l, int r) { if(l == r) st[node].push_back(l); else{ build(node*2, l, (l+r)/2); build(node*2+1, (l+r)/2+1, r); int j = 0; for(int i = 0; i < st[node*2].size(); i++){ while(j < st[node*2+1].size() && h[st[node*2+1][j]] < h[st[node*2][i]]){ st[node].push_back(st[node*2+1][j]); j++; } st[node].push_back(st[node*2][i]); } while(j < st[node*2+1].size()){ st[node].push_back(st[node*2+1][j]); j++; } } } int query(int node, int l, int r, int tl, int tr, int val) { if(l > tr || r < tl) return -1; if(l >= tl && r <= tr){ int p = lower_bound(st[node].begin(), st[node].end(), val, cmp) - st[node].begin(); if(p == 0) return -1; else return st[node][p-1]; } else{ int x = query(node*2, l, (l+r)/2, tl, tr, val); int y = query(node*2+1, (l+r)/2+1, r, tl, tr, val); if(x == -1) return y; if(y == -1) return x; if(h[x] < h[y]) return y; else return x; } } int query_atleast(int node, int l, int r, int tl, int tr, int val) { if(l > tr || r < tl) return -1; if(l >= tl && r <= tr){ int p = lower_bound(st[node].begin(), st[node].end(), val, cmp) - st[node].begin(); if(p == st[node].size()) return -1; else return st[node][p-1]; } else{ int x = query_atleast(node*2, l, (l+r)/2, tl, tr, val); int y = query_atleast(node*2+1, (l+r)/2+1, r, tl, tr, val); if(x == -1) return y; if(y == -1) return x; if(h[x] > h[y]) return y; else return x; } } void init(int N, vector<int> H) { n = N; for(int i = 0; i < n; i++) h[i+1] = H[i]; h[0] = h[n+1] = 1e9; ri[n+1] = n+1; for(int i = 1; i <= n; i++){ le[i] = i-1; while(h[le[i]] < h[i]) le[i] = le[le[i]]; } for(int i = n; i >= 1; i--){ ri[i] = i+1; while(h[ri[i]] < h[i]) ri[i] = ri[ri[i]]; } for(int i = 1; i <= n; i++){ if(h[le[i]] > h[ri[i]]) jump_max[i][0] = le[i]; else jump_max[i][0] = ri[i]; jumpri[i][0] = ri[i]; } jumpri[n+1][0] = jump_max[n+1][0] = n+1; for(int j = 1; j <= 19; j++){ for(int i = 0; i <= n+1; i++){ jump_max[i][j] = jump_max[jump_max[i][j-1]][j-1]; jumpri[i][j] = jumpri[jumpri[i][j-1]][j-1]; } } build(1, 1, n); } int minimum_jumps(int l1, int r1, int l2, int r2) { l1++; r1++; l2++; r2++; //We have l2 = r2 //First check if it's possible int p1 = query_atleast(1, 1, n, l1, r1, l2); l1 = query(1, 1, n, max(p1+1, l1), r1, l2); //We greedily choose the largest node if(l1 == -1) return -1; int u = l1; for(int i = 19; i >= 0; i--) if(jumpri[u][i] <= l2) u = jumpri[u][i]; if(u < l2) return -1; //Now find the best answer int ans = 0; u = l1; for(int i = 19; i >= 0; i--) if(h[jump_max[u][i]] < h[l2]){ u = jump_max[u][i]; ans += (1 << i); } for(int i = 19; i >= 0; i--) if(jumpri[u][i] <= l2){ u = jumpri[u][i]; ans += (1 << i); } return ans; }
#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...