# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
413353 | mat_v | 밀림 점프 (APIO21_jumps) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "jumps.h"
#include <bits/stdc++.h>
#define ff(i,a,b) for(int (i) = (a); (i) <= (b); ++(i))
#define fb(i,a,b) for(int (i) = (a); (i) >= (b); --(i))
using namespace std;
int n;
int niz[200005];
int levo[200005][20];
int desno[200005][20];
int pravi[200005][20];
int poz[200005];
void init(int N, std::vector<int> H) {
n = N;
ff(i,0,n - 1){
niz[i + 1] = H[i];
poz[niz[i + 1]] = i+1;
}
stack<int> s;
ff(i,1,n){
while(!s.empty() && niz[s.top()] < niz[i])s.pop();
if(!s.empty())levo[i][0] = s.top();
s.push(i);
}
while(!s.empty())s.pop();
fb(i,n,1){
while(!s.empty() && niz[s.top()] < niz[i])s.pop();
if(!s.empty())desno[i][0] = s.top();
s.push(i);
}
fb(i,n,1){
ff(j,1,18)desno[i][j] = desno[desno[i][j - 1]][j - 1];
}
ff(i,1,n){
ff(j,1,18)levo[i][j] = levo[levo[i][j - 1]][j - 1];
}
fb(i,n - 1,1){
int sta = poz[i];
int lv = levo[sta][0], rv = desno[sta][0];
if(niz[lv] > niz[rv])pravi[sta][0] = lv;
else pravi[sta][0] = rv;
ff(j,1,18)pravi[sta][j] = pravi[pravi[sta][j - 1]][j - 1];
}
}
int dist(int x, int y){
if(niz[y] < niz[x])return -1;
int ans = 0;
int lv = x;
int poc = y;
fb(j,18,0){
if(pravi[lv][j] && niz[pravi[lv][j]] < niz[poc]){
ans += (1<<j);
lv = pravi[lv][j];
}
}
fb(j,18,0){
if(desno[lv][j] && niz[desno[lv][j]] < niz[poc]){
ans += (1<<j);
lv = desno[lv][j];
}
}
if(desno[lv][0] == poc)return ans+1;
return -1;
}
int minimum_jumps(int A, int B, int C, int D) {
A++;
B++;
C++;
D++;
int l1,r1,l2,r2;
l1 = A, r1 = B, l2 = C, r2 = D;
int tr = l2;
fb(j,18,0){
if(desno[tr][j] && desno[tr][j] <= r2)tr = desno[tr][j];
}
int val = niz[tr];
int lv = r1;
fb(j,18,0){
if(levo[lv][j] && levo[lv][j] >= l1 && niz[levo[lv][j]] < val)lv = levo[lv][j];
}
if(niz[lv] > val)return -1;
int ans = 1e9;
ff(j,l2,r2){
if(dist(lv,j) > 0)ans = min(ans, dist(lv,j));
}
if(ans == 1e9)return -1;
int mks = 0;
int idx = 0;
if(r1+1 <= l2-1){
idx = r1+1;
fb(j,18,0){
if(desno[idx][j] && desno[idx][j] <= l2-1)idx = desno[idx][j];
}
mks = niz[idx];
}
if(mks > val)return -1;
if(maks < niz[lv])return 1;
int res = 0;
fb(j,18,0){
if(pravi[lv][j] && niz[pravi[lv][j]] < mks){
res += (1<<j);
lv = pravi[lv][j];
}
}
res+=2;
return res;
}
/*
7 3
3 2 1 6 4 5 7
4 4 6 6
1 3 5 6
0 1 2 2
*/