#include "jumps.h"
#include <bits/stdc++.h>
using namespace std;
#define inf 1000000
vector<vector<int>> edges;
vector<int> H;
vector<vector<int>> big,small,spt;
int N;
int k;
void init(int iN, std::vector<int> iH) {
N = iN;
H = iH;
// create DAG using monotic array
stack<int> st;
edges.resize(N+1);
// create front
for(int i = 0;i < N;i++){
while(!st.empty() && st.top() < H[i]){
st.pop();
}
if(!st.empty()){
edges[H[i]].push_back(st.top());
}
st.push(H[i]);
}
while(!st.empty()) st.pop();
// from back
for(int i = N-1;i >= 0;i--){
while(!st.empty() && st.top() < H[i]){
st.pop();
}
if(!st.empty()){
edges[H[i]].push_back(st.top());
}
st.push(H[i]);
}
for(auto &i:edges){
if(i.size() == 0){
i.push_back(-1);
i.push_back(-1);
continue;
}
if(i.size() == 1){
i.push_back(i[0]);
continue;
}
if(i[0] < i[1]) swap(i[0],i[1]);
}
// edges[0] -> big, edges[1] -> small
//create edges ok, lets create binary jump
k = __lg(N+1);
big = small = vector<vector<int>>(k+1,vector<int>(N+1,0));
// zero layer
for(int i = 1;i <= N;i++){
big[0][i] = edges[i][0];
small[0][i] = edges[i][1];
}
for(int l = 1;l <= k;l++){
for(int i = 1;i <= N;i++){
if(big[l-1][i] == -1){
big[l][i] = -1;
}else{
big[l][i] = big[l-1][big[l-1][i]];
}
if(small[l-1][i] == -1){
small[l][i] = -1;
}else{
small[l][i] = small[l-1][small[l-1][i]];
}
}
}
spt = vector<vector<int>>(k+1,vector<int>(N,0));// range max;
spt[0] = H;
for(int l = 1;l <= k;l++){
for(int i = 0;i+(1 << (l-1)) < N;i++){
spt[l][i] = max(spt[l-1][i],spt[l-1][i+(1 << (l-1))]);
}
}
// sparse table
}
int get_max(int l,int r){
int len = (r-l+1);
int layer = __lg(len);
return max(spt[layer][l],spt[layer][r-(1 << layer)+1]);
}
int minimum_jumps(int A, int B, int C, int D) {
// A <= B and C == D
int endPoint = get_max(C,D);
// add find start point
int cur = B;
if(get_max(B,C-1) > endPoint)return -1;
{
int bottom = A;
int top = B;
while(bottom <= top){
int mid = (bottom+top)/2;
if(get_max(mid,C-1) < endPoint){
// ok
cur = min(cur,mid);
top = mid-1;
}else{
bottom = mid+1;
}
}
}
cur = get_max(cur,B);// value
// add find endPoint point
{
int bottom = C;
int top = D;
while(bottom <= top){
int mid = (bottom+top)/2;
if(get_max(C,mid) > max(cur,get_max(B,C-1))){
// ok;
endPoint = get_max(C,mid);
top = mid-1;
}else{
bottom = mid+1;
}
}
}
// cout << cur << " " << endPoint << endl;
// cur is the start point
int cnt = 0;
for(int l = k;l >= 0;l--){
if(big[l][cur] != -1 && big[l][cur] <= endPoint){
cur = big[l][cur];
cnt+=(1 << l);
}
}
for(int l = k;l >= 0;l--){
if(small[l][cur] != -1 && small[l][cur] <= endPoint){
cur = small[l][cur];
cnt+=(1 << l);
}
}
if(cur != endPoint){
// cout << "?";
return -1;
}else{
return cnt;
}
}
# | 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... |