이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "jumps.h"
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define all(x) x.begin(),x.end()
#define vf first
#define vs second
const int mod = 998244353;
const int N = 200001 , B = 20;
int n;
int arr[N] , left_edge[N] , right_edge[N];
vector<int> gl[N],gr[N],gmx[N];
int upl[N][B], upr[N][B], upmx[N][B];
void dfsl(int node , int par){
upl[node][0] = par;
for(int i = 1; i < B; i++){
upl[node][i] = upl[upl[node][i-1]][i-1];
}
for(int i : gl[node]){
dfsl(i,node);
}
}
void dfsr(int node , int par){
upr[node][0] = par;
for(int i = 1; i < B; i++){
upr[node][i] = upr[upr[node][i-1]][i-1];
}
for(int i : gr[node]){
dfsr(i,node);
}
}
void dfsmx(int node , int par){
upmx[node][0] = par;
for(int i = 1 ; i < B; i++){
upmx[node][i] = upmx[upmx[node][i-1]][i-1];
}
for(int i : gmx[node]){
dfsmx(i,node);
}
}
void init(int n1 , vector<int> h){
n = n1;
for(int i = 0; i < n; i++)
arr[i] = h[i];
stack<pair<int,int>> s;
s.push(mp(1e9+10,n));
memset(left_edge,-1,sizeof left_edge);
memset(right_edge,-1,sizeof right_edge);
for(int i = 0; i < n; i++){
while(s.size() && s.top().vf < arr[i]){
s.pop();
}
if(s.size())
left_edge[i] = s.top().vs;
s.push(mp(arr[i],i));
}
while(s.size())s.pop();
s.push(mp(1e9+10,n));
for(int i = n - 1; i >= 0; i--){
while(s.size() && s.top().vf < arr[i]){
s.pop();
}
if(s.size())
right_edge[i] = s.top().vs;
s.push(mp(arr[i],i));
}
for(int i = 0; i < n; i++){
gl[left_edge[i]].pb(i);
gr[right_edge[i]].pb(i);
if(left_edge[i] != n || right_edge[i] != n){
if(left_edge[i] == n)gmx[right_edge[i]].pb(i);
else if(right_edge[i] == n)gmx[left_edge[i]].pb(i);
else if(arr[left_edge[i]] > arr[right_edge[i]])gmx[left_edge[i]].pb(i);
else gmx[right_edge[i]].pb(i);
}
}
dfsl(n,n);
dfsr(n,n);
int mx_pos = -1 , mx = -1;
for(int i = 0; i < n; i++){
if(mx < arr[i]){
mx = arr[i];
mx_pos = i;
}
}
dfsmx(mx_pos,mx_pos);
}
int binary_liftingl(int start , int stop){
for(int i = B-1; i >= 0; i--){
if(upl[start][i]!=n && upl[start][i] > stop){
start = upl[start][i];
}
}
return start;
}
int binary_liftingr(int start , int stop){
for(int i = B-1; i >= 0; i--){
if(upr[start][i]!=n && upr[start][i] < stop){
start = upr[start][i];
}
}
return start;
}
int final_bl_l(int start , int stop , int mx , int end , int s){
int ans = 0;
for(int i = B-1; i >= 0; i--){
if(arr[upmx[start][i]] < stop){
ans += (1 << i);
start = upmx[start][i];
}
}
if(arr[start] == stop)return ans;
int x = start;
int res = 0;
for(int i = B-1; i >= 0; i--){
if(upl[x][i]!=n && arr[upl[x][i]] < stop){
res += (1 << i);
x = upl[x][i];
}
}
res++;
int res1 = N;
int node = upmx[start][0];
if(node != n && node <= end && node >= s)res1 = 1;
else res1 = 2;
if(arr[node] < mx){
ans += min(res , res1);
}
else ans += res;
return ans;
}
int final_bl_r(int start , int stop , int mx , int end , int s){
int ans = 0;
for(int i = B-1; i >= 0; i--){
if(arr[upmx[start][i]] < stop){
ans += (1 << i);
start = upmx[start][i];
}
}
if(arr[start] == stop)return ans;
int x = start;
int res = 0;
for(int i = B-1; i >= 0; i--){
if(upr[x][i]!=n && arr[upr[x][i]] < stop){
res += (1 << i);
x = upr[x][i];
}
}
res++;
int res1 = N;
int node = upmx[start][0];
if(node != n && node >= end && node <= s)res1 = 1;
else res1 = 2;
if(arr[node] < mx){
ans += min(res , res1);
}
else ans += res;
return ans;
}
int bl_l(int start , int end , int mx){
for(int i = B-1; i >= 0; i--){
if(upr[start][i] != n && upr[start][i] <= end && arr[upr[start][i]] < mx){
start = upr[start][i];
}
}
return start;
}
int bl_r(int start , int end , int mx){
for(int i = B-1; i >= 0; i--){
if(upl[start][i] != n && upl[start][i] >= end && arr[upl[start][i]] < mx){
start = upl[start][i];
}
}
return start;
}
int type_left(int a , int b , int c , int d){
int pos = upl[binary_liftingl(a,d)][0];
if(pos < c || pos == n)return -1;
int mx_pos = binary_liftingl(pos , c-1);
int mx = arr[mx_pos];
return final_bl_l(bl_l(a,b,arr[pos]),arr[pos],mx,b,a);
}
int type_right(int a , int b , int c , int d){
int pos = upr[binary_liftingr(b,c)][0];
if(pos > d || pos == n)return -1;
int mx_pos = binary_liftingr(pos , d+1);
int mx = arr[mx_pos];
return final_bl_r(bl_r(b,a,arr[pos]),arr[pos],mx,a,b);
}
int minimum_jumps(int a, int b, int c, int d){
if(!(c > b || a > d))return 0;
if(a > c)return type_left(a,b,c,d);
else return type_right(a,b,c,d);
}
# | 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... |