Submission #859629

#TimeUsernameProblemLanguageResultExecution timeMemory
859629boris_mihovRainforest Jumps (APIO21_jumps)C++17
100 / 100
798 ms67704 KiB
#include "jumps.h" #include <algorithm> #include <iostream> #include <numeric> #include <cassert> #include <vector> #include <stack> typedef long long llong; const int MAXN = 200000 + 10; const int MAXLOG = 20; const llong INF = 1e18; const int INTINF = 2e9; int n; int h[MAXN]; int firstR[MAXN]; int firstL[MAXN]; std::stack <int> st; struct SparseRMQ { int sparse[MAXLOG][MAXN]; int getLOG[MAXN]; void build() { for (int i = 1 ; i <= n ; ++i) { sparse[0][i] = h[i]; } for (int log = 1 ; (1 << log) <= n ; ++log) { for (int i = 1 ; i + (1 << log) - 1 <= n ; ++i) { sparse[log][i] = std::max(sparse[log - 1][i], sparse[log - 1][i + (1 << log - 1)]); } } for (int i = 1 ; i <= n ; ++i) { getLOG[i] = getLOG[i - 1]; if ((1 << getLOG[i] + 1) < i) getLOG[i]++; } } int findMAX(int l, int r) { int log = getLOG[r - l + 1]; return std::max(sparse[log][l], sparse[log][r - (1 << log) + 1]); } }; SparseRMQ sparseMAX; struct SparseLCA { int sparse[MAXLOG][MAXN]; void build(int p[]) { for (int i = 1 ; i <= n ; ++i) { sparse[0][i] = p[i]; } for (int log = 1 ; (1 << log) <= n ; ++log) { for (int i = 1 ; i <= n ; ++i) { sparse[log][i] = sparse[log - 1][sparse[log - 1][i]]; } } } int kth(int log, int node) { return sparse[log][node]; } }; SparseLCA sparseL; SparseLCA sparseR; SparseLCA sparseLR; int par[MAXN]; void init(int N, std::vector <int> H) { n = N; for (int i = 0 ; i < n ; ++i) { h[i + 1] = H[i]; } h[0] = h[n + 1] = INTINF; st.push(0); for (int i = 1 ; i <= n ; ++i) { while (h[i] > h[st.top()]) { st.pop(); } firstL[i] = st.top(); st.push(i); } while (st.size()) st.pop(); st.push(n + 1); for (int i = n ; i >= 1 ; --i) { while (h[i] > h[st.top()]) { st.pop(); } firstR[i] = st.top(); st.push(i); } firstR[0] = firstR[n + 1] = n + 1; for (int i = 1 ; i <= n ; ++i) { par[i] = firstL[i]; if (h[firstR[i]] > h[par[i]]) par[i] = firstR[i]; } sparseMAX.build(); sparseL.build(firstL); sparseR.build(firstR); sparseLR.build(par); } int minimum_jumps(int a, int b, int c, int d) { a++; b++; c++; d++; int maxC = sparseMAX.findMAX(c, d); if (sparseMAX.findMAX(b, c - 1) > maxC) { return -1; } int node = b; for (int log = MAXLOG - 1 ; log >= 0 ; --log) { if (sparseL.kth(log, node) >= a && h[sparseL.kth(log, node)] <= maxC) { node = sparseL.kth(log, node); } } if (firstR[node] >= c) { return 1; } int res = 0; for (int log = MAXLOG - 1 ; log >= 0 ; --log) { if (h[sparseLR.kth(log, node)] <= maxC && firstR[sparseLR.kth(log, node)] < c) { res += (1 << log); node = sparseLR.kth(log, node); } } assert(firstR[node] < c); if (h[sparseLR.kth(0, node)] <= maxC) { assert(firstR[sparseLR.kth(0, node)] >= c); node = sparseLR.kth(0, node); node = sparseR.kth(0, node); assert(c <= node && node <= d); res += 2; return res; } assert(h[firstR[node]] <= maxC); for (int log = MAXLOG - 1 ; log >= 0 ; --log) { if (firstR[sparseR.kth(log, node)] < c) { res += (1 << log); node = sparseR.kth(log, node); } } assert(firstR[node] < c); node = firstR[node]; assert(firstR[node] <= d); node = firstR[node]; res += 2; assert(c <= node && node <= d); return res; }

Compilation message (stderr)

jumps.cpp: In member function 'void SparseRMQ::build()':
jumps.cpp:37:93: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
   37 |                 sparse[log][i] = std::max(sparse[log - 1][i], sparse[log - 1][i + (1 << log - 1)]);
      |                                                                                         ~~~~^~~
jumps.cpp:44:33: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
   44 |             if ((1 << getLOG[i] + 1) < i) getLOG[i]++;
      |                       ~~~~~~~~~~^~~
#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...