제출 #1162901

#제출 시각아이디문제언어결과실행 시간메모리
1162901brintonRainforest Jumps (APIO21_jumps)C++20
48 / 100
441 ms57696 KiB
#include "jumps.h" #include <bits/stdc++.h> using namespace std; #define inf 1000000 vector<vector<int>> edges; vector<int> H; vector<vector<int>> big,small,spt; int N; int k; void init(int iN, std::vector<int> iH) { N = iN; H = iH; // create DAG using monotic array stack<int> st; edges.resize(N+1); // create front for(int i = 0;i < N;i++){ while(!st.empty() && st.top() < H[i]){ st.pop(); } if(!st.empty()){ edges[H[i]].push_back(st.top()); } st.push(H[i]); } while(!st.empty()) st.pop(); // from back for(int i = N-1;i >= 0;i--){ while(!st.empty() && st.top() < H[i]){ st.pop(); } if(!st.empty()){ edges[H[i]].push_back(st.top()); } st.push(H[i]); } for(auto &i:edges){ if(i.size() == 0){ i.push_back(-1); i.push_back(-1); continue; } if(i.size() == 1){ i.push_back(i[0]); continue; } if(i[0] < i[1]) swap(i[0],i[1]); } // edges[0] -> big, edges[1] -> small //create edges ok, lets create binary jump k = __lg(N+1); big = small = vector<vector<int>>(k+1,vector<int>(N+1,0)); // zero layer for(int i = 1;i <= N;i++){ big[0][i] = edges[i][0]; small[0][i] = edges[i][1]; } for(int l = 1;l <= k;l++){ for(int i = 1;i <= N;i++){ if(big[l-1][i] == -1){ big[l][i] = -1; }else{ big[l][i] = big[l-1][big[l-1][i]]; } if(small[l-1][i] == -1){ small[l][i] = -1; }else{ small[l][i] = small[l-1][small[l-1][i]]; } } } spt = vector<vector<int>>(k+1,vector<int>(N,0));// range max; spt[0] = H; for(int l = 1;l <= k;l++){ for(int i = 0;i+(1 << (l-1)) < N;i++){ spt[l][i] = max(spt[l-1][i],spt[l-1][i+(1 << (l-1))]); } } // sparse table } int get_max(int l,int r){ int len = (r-l+1); int layer = __lg(len); return max(spt[layer][l],spt[layer][r-(1 << layer)+1]); } int minimum_jumps(int A, int B, int C, int D) { // A <= B and C == D int endPoint = get_max(C,D); // add find start point int cur = B; if(get_max(B,C-1) > endPoint)return -1; { int bottom = A; int top = B; while(bottom <= top){ int mid = (bottom+top)/2; if(get_max(mid,C-1) < endPoint){ // ok cur = min(cur,mid); top = mid-1; }else{ bottom = mid+1; } } } cur = get_max(cur,B);// value // add find endPoint point { int bottom = C; int top = D; while(bottom <= top){ int mid = (bottom+top)/2; if(get_max(C,mid) > max(cur,get_max(B,C-1))){ // ok; endPoint = get_max(C,mid); top = mid-1; }else{ bottom = mid+1; } } } // cout << cur << " " << endPoint << endl; // cur is the start point int cnt = 0; for(int l = k;l >= 0;l--){ if(big[l][cur] != -1 && big[l][cur] <= endPoint){ cur = big[l][cur]; cnt+=(1 << l); } } for(int l = k;l >= 0;l--){ if(small[l][cur] != -1 && small[l][cur] <= endPoint){ cur = small[l][cur]; cnt+=(1 << l); } } if(cur != endPoint){ // cout << "?"; return -1; }else{ return cnt; } }
#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...