Submission #1125394

#TimeUsernameProblemLanguageResultExecution timeMemory
1125394SamueleVidRainforest Jumps (APIO21_jumps)C++20
23 / 100
1104 ms71912 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long int N; vector<int> H; constexpr ll PW = 262144; constexpr ll LOG = 20; struct segment { vector<ll> seg; segment() { seg.assign(2 * PW, 1e9); } void update(int x, ll d) { x += PW; seg[x] = d; x /= 2; while (x >= 1) { seg[x] = min(seg[2 * x], seg[2 * x + 1]); x /= 2; } } ll query(int l, int r) { l += PW; r += PW; ll sol = 1e9; while (l <= r) { if (l % 2 == 1) { sol = min(sol, seg[l]); l ++; } if (r % 2 == 0) { sol = min(sol, seg[r]); r --; } l /= 2; r /= 2; } return sol; } void clear() { for (int i = 0; i < 2 * PW; i ++) seg[i] = 1e9; } }; struct binlift { int N, LOG; vector<int> p; vector<int> depth; vector<vector<int>> bl; vector<vector<int>> adj; binlift() {} binlift(int N_, int LOG_, vector<int> p_) { N = N_; LOG = LOG_; p = p_; depth.resize(N); bl.assign(LOG_, vector<int>(N)); adj.resize(N); for (int i = 0; i < N; i ++) { if (p[i] != -1) adj[p[i]].push_back(i); } for (int i = 0; i < N; i ++) { if (p[i] == -1) { depth[i] = 0; dfs_depth(i); } } for (int i = 0; i < N; i ++) { bl[0][i] = (p[i] != -1) ? p[i] : i; } for (int p = 1; p < LOG; p ++) { for (int i = 0; i < N; i ++) { bl[p][i] = bl[p - 1][bl[p - 1][i]]; } } // for (int p = 0; p < LOG; p ++) { // cout << "p : " << p << " -> "; // for (int i = 0; i < N; i ++) cout << bl[p][i] << " "; // cout << '\n'; // } } void dfs_depth(int u) { for (auto x : adj[u]) { depth[x] = depth[u] + 1; dfs_depth(x); } } int n_th_ancestor(int u, int n) { // cout << "n, u : " << n << " " << u << '\n'; for (int i = LOG - 1; i >= 0; i --) { if (n & (1 << i)) { // cout << "2 ^ " << i << " esimo parent di " << u << '\n'; u = bl[i][u]; } // cout << "-> " << u << '\n'; } return u; } }; segment seg; vector<int> p_max; vector<int> p_dx; binlift bl_max, bl_dx; void init(int N, vector<int> H) { ::N = N; ::H = H; vector<int> inv_H(N + 1); for (int i = 0; i < N; i ++) inv_H[H[i]] = i; p_max.assign(N, -1); p_dx.assign(N, -1); // a destra for (int i = N - 1; i >= 0; i --) { int u = seg.query(H[i] + 1, N); if (u != 1e9) { p_dx[i] = u; p_max[i] = u; } seg.update(H[i], i); } seg.clear(); // a sinistra for (int i = 0; i < N; i ++) { int u = -seg.query(H[i] + 1, N); if (u != -1e9) { if (p_max[i] != -1 && H[u] > H[p_max[i]]) p_max[i] = u; } seg.update(H[i], -i); } bl_max = binlift(N, LOG, p_max); bl_dx = binlift(N, LOG, p_dx); } int minimum_jumps(int A, int B, int C, int D) { // A == B e C == D // cout << "a, c : " << A << " " << C << '\n'; int k = -1; for (int p = PW; p >= 1; p /= 2) { // cout << "k, p, k + p : " << k << " " << p << " " << k + p << '\n'; int u = bl_max.n_th_ancestor(A, (p + k)); if (bl_dx.depth[C] > bl_dx.depth[u]) continue; int v = bl_dx.n_th_ancestor(u, bl_dx.depth[u] - bl_dx.depth[C]); if (v == C) k += p; } if (k == -1) return -1; int u = bl_max.n_th_ancestor(A, k); int sol = (bl_dx.depth[u] - bl_dx.depth[C]) + (bl_max.depth[A] - bl_max.depth[u]); return sol; } // int main() { // int N, Q; // cin >> N >> Q; // vector<int> H(N); // for(int &x: H) cin >> x; // init(N, H); // for(int i=0; i<Q; i++){ // int A, B, C, D; // cin >> A >> B >> C >> D; // cout << minimum_jumps(A, B, C, D) << "\n"; // } // }
#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...