Submission #855127

#TimeUsernameProblemLanguageResultExecution timeMemory
855127PoPularPlusPlusRainforest Jumps (APIO21_jumps)C++17
100 / 100
976 ms86608 KiB
#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 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...