This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |