Submission #1038163

#TimeUsernameProblemLanguageResultExecution timeMemory
1038163AndreyRainforest Jumps (APIO21_jumps)C++14
100 / 100
843 ms42068 KiB
#include "jumps.h"
#include<bits/stdc++.h>
#include <vector>
using namespace std;

int n;
vector<int> haha(200010);
vector<int> lb(200001);
vector<int> rb(200001);
vector<pair<int,int>> seg(1000001);
int big[200001][18];
int sm[200001][18];

void build(int l, int r, int x) {
    if(l == r) {
        seg[x] = {haha[l],l};
        return;
    }
    int mid = (l+r)/2;
    build(l,mid,x*2);
    build(mid+1,r,x*2+1);
    seg[x] = max(seg[x*2],seg[x*2+1]);
}

pair<int,int> dude(int l, int r, int ql, int qr, int x) {
    if(l == ql && r == qr) {
        return seg[x];
    }
    int mid = (l+r)/2;
    if(qr <= mid) {
        return dude(l,mid,ql,qr,x*2);
    }
    else if(ql > mid) {
        return dude(mid+1,r,ql,qr,x*2+1);
    }
    else {
        return max(dude(l,mid,ql,mid,x*2),dude(mid+1,r,mid+1,qr,x*2+1));
    }
}

void calc(int x) {
    stack<pair<int,int>> idk;
    for(int i = 0; i < n; i++) {
        while(!idk.empty() && idk.top().first < haha[i]) {
            idk.pop();
        }
        int c;
        if(idk.empty()) {
            c = n;
        }
        else {
            if(x == 0) {
                c = idk.top().second;
            }
            else {
                c = n-idk.top().second-1;
            }
        }
        if(x == 0) {
            lb[i] = c;
        }
        else {
            rb[n-i-1] = c;
        }
        idk.push({haha[i],i});
    }
}

void init(int N, std::vector<int> H) {
    n = N;
    haha[n] = 0;
    lb[n] = n;
    rb[n] = n;
    for(int i = 0; i < n; i++) {
        haha[i] = H[i];
    }
    calc(0);
    for(int i = 0; i < n/2; i++) {
        swap(haha[i],haha[n-i-1]);
    }
    calc(1);
    for(int i = 0; i < n/2; i++) {
        swap(haha[i],haha[n-i-1]);
    }
    for(int i = 0; i <= n; i++) {
        if(haha[lb[i]] > haha[rb[i]]) {
            big[i][0] = lb[i];
            sm[i][0] = rb[i];
        }
        else {
            big[i][0] = rb[i];
            sm[i][0] = lb[i];
        }
    }
    for(int i = 1; i < 18; i++) {
        for(int j = 0; j <= n; j++) {
            big[j][i] = big[big[j][i-1]][i-1];
            sm[j][i] = sm[sm[j][i-1]][i-1];
        }
    }
    build(0,n-1,1);
}

int minimum_jumps(int a, int b, int c, int d) {
    int p = dude(0,n-1,c,d,1).second;
    int q = lb[p];
    if(q == n) {
        q = -1;
    }
    a = max(a,q+1);
    if(a > b) {
        return -1;
    }
    int y = dude(0,n-1,a,b,1).second;
    int x = y,ans = 0;
    if(rb[x] >= c && rb[x] <= d) {
        return 1;
    }
    for(int i = 17; i >= 0; i--) {
        int e = big[x][i];
        if(e != n && haha[e] <= haha[p] && (!(e >= c && e <= d)) && (!(lb[e] >= c && lb[e] <= d)) && (!(rb[e] >= c && rb[e] <= d))) {
            ans+=(1 << i);
            x = e;
        }
        else if(i == 0) {
            if(e != n && haha[e] <= haha[p]) {
                return ans+2;
            }
        }
    }
    int e = big[x][0];
    if(lb[e] >= c && lb[e] <= d) {
        return ans+2;
    }
    if(rb[e] >= c && rb[e] <= d) {
        return ans+2;
    }
    for(int i = 17; i >= 0; i--) {
        int e = sm[x][i];
        if(e != n && haha[e] <= haha[p] && (!(e >= c && e <= d)) && (!(lb[e] >= c && lb[e] <= d)) && (!(rb[e] >= c && rb[e] <= d))) {
            ans+=(1 << i);
            x = e;
        }
    }
    return ans+2;
}
#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...