# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1119328 | vako_p | 밀림 점프 (APIO21_jumps) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const int mxN = 3e5 + 5;
ll n,a[mxN],p[mxN][25],p1[mxN][25],p2[mxN][25],L[mxN],R[mxN];
stack<ll> st;
void init(int N, int H[]){
n = N;
for(int i = 1; i <= n; i++) a[i] = H[i - 1];
a[0] = a[n + 1] = 1e9;
st.push(0);
for(int i = 1; i <= n; i++){
while(!st.empty()){
if(a[st.top()] < a[i]) st.pop();
else break;
}
L[i] = st.top();
st.push(i);
}
while(!st.empty()) st.pop();
st.push(n + 1);
for(int i = n; i > 0; i--){
while(!st.empty()){
if(a[st.top()] < a[i]) st.pop();
else break;
}
R[i] = st.top();
st.push(i);
}
for(int i = 0; i <= 20; i++) p[n + 1][i] = p1[n + 1][i] = p2[n + 1][i] = n + 1;
for(int i = n; i > 0; i--){
p[i][0] = R[i];
for(int j = 1; j <= 20; j++) p[i][j] = p[p[i][j - 1]][j - 1];
}
for(int i = 1; i <= n; i++){
p2[i][0] = L[i];
for(int j = 1; j <= 20; j++) p2[i][j] = p2[p2[i][j - 1]][j - 1];
}
for(int j = 0; j <= 20; j++){
for(int i = 1; i <= n; i++){
if(j == 0){
if(a[R[i]] > a[L[i]]) p1[i][j] = R[i];
else p1[i][j] = L[i];
continue;
}
p1[i][j] = p1[p1[i][j - 1]][j - 1];
}
}
}
ll f(ll idx, ll num){
ll ans = 0;
for(int i = 20; i >= 0; i--){
if(a[p[idx][i]] < num){
idx = p[idx][i];
ans += (1LL << i);
}
}
return ans;
}
int minimum_jumps(int A, int B, int C, int D){
A++;B++;C++;D++;
ll idx = B,num;
for(int i = 20; i >= 0; i--) if(p[idx][i] < C) idx = p[idx][i];
if(idx == B) num = 0;
else num = a[idx];
if(p[idx][0] > D) return -1;
idx = B;
bool ok = (a[idx] < num);
for(int i = 20; i >= 0; i--){
if(p2[idx][i] >= A){
if(a[p2[idx][i]] > num){
ok = false;
continue;
}
idx = p2[idx][i];
}
}
ll ans = f(idx, num + 1) + 1;
if(ok){
ll ans1 = 1;
for(int i = 20; i >= 0; i--){
if(a[p1[idx][i]] < num){
ans1 += (1LL << i);
idx = p1[idx][i];
}
}
if(p1[idx][0] != 0 and p[p1[idx][0]][0] <= D) return min(ans, ans1 + 1LL);
return min(ans1 + f(idx, num + 1), ans);
}
return ans;
}
#ifdef LOCAL
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
freopen("task.inp", "r", stdin);
freopen("task.out", "w", stdout);
int N, Q;
cin >> N >> Q;
int H[mxN];
for(int i = 0; i < N; ++i){
cin >> H[i];
}
init(N, H);
for(int i = 0; i < Q; ++i){
int a, b, c, d;
cin >> a >> b >> c >> d;
cout << minimum_jumps(a, b, c, d) << '\n';
}
return 0;
}
#endif //LOCAL