제출 #1162845

#제출 시각아이디문제언어결과실행 시간메모리
1162845brintonRainforest Jumps (APIO21_jumps)C++20
48 / 100
402 ms57704 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 // add find start point int cur = B; if(get_max(B,C-1) > H[C])return -1; int bottom = A; int top = B; while(bottom <= top){ int mid = (bottom+top)/2; if(get_max(mid,C-1) < H[C]){ // ok cur = min(cur,mid); top = mid-1; }else{ bottom = mid+1; } } cur = get_max(cur,B); // cur is the start point int cnt = 0; for(int l = k;l >= 0;l--){ if(big[l][cur] != -1 && big[l][cur] <= H[C]){ cur = big[l][cur]; cnt+=(1 << l); } } for(int l = k;l >= 0;l--){ if(small[l][cur] != -1 && small[l][cur] <= H[C]){ cur = small[l][cur]; cnt+=(1 << l); } } if(cur != H[C]){ return -1; }else{ return cnt; } } // grader // #include "jumps.h" // #include <cassert> // #include <cstdio> // #include <vector> // int main() { // int N, Q; // assert(2 == scanf("%d %d", &N, &Q)); // std::vector<int> H(N); // for (int i = 0; i < N; ++i) { // assert(1 == scanf("%d", &H[i])); // } // init(N, H); // for (int i = 0; i < Q; ++i) { // int A, B, C, D; // assert(4 == scanf("%d %d %d %d", &A, &B, &C, &D)); // printf("%d\n", minimum_jumps(A, B, C, D)); // } // return 0; // }
#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...