제출 #566902

#제출 시각아이디문제언어결과실행 시간메모리
566902amunduzbaev밀림 점프 (APIO21_jumps)C++17
23 / 100
4073 ms78324 KiB
#include "jumps.h" #ifndef EVAL #include "stub.cpp" #endif #include "bits/stdc++.h" using namespace std; const int B = 205; const int N = 2e5 + 5; const int lg = 18; int mx[N][lg], mn[N][lg], h[N], pos[N]; int lx[N], rx[N], prec[N/B][N]; struct ST{ vector<int> tree[N << 2]; int mx[N << 2]; void build(int lx = 0, int rx = N, int x = 1){ if(lx == rx) { tree[x].push_back(h[lx]); return; } int m = (lx + rx) >> 1; build(lx, m, x << 1); build(m + 1, rx, x << 1 | 1); tree[x].insert(tree[x].end(), tree[x<<1].begin(), tree[x<<1].end()); tree[x].insert(tree[x].end(), tree[x<<1|1].begin(), tree[x<<1|1].end()); sort(tree[x].begin(), tree[x].end()); mx[x] = max(mx[x<<1], mx[x<<1|1]); } int get_(int l, int r, int v, int lx = 0, int rx = N, int x = 1){ if(lx > r || rx < l) return -1; if(lx >= l && rx <= r){ if(mx[x] <= v) return -1; if(lx == rx) return lx; int m = (lx + rx) >> 1; if(mx[x << 1 | 1] > v) return get_(l, r, v, m + 1, rx, x<<1 | 1); else return get_(l, r, v, lx, m, x << 1); } int m = (lx + rx) >> 1; int R = get_(l, r, v, m + 1, rx, x << 1 | 1); if(~R) return R; return get_(l, r, v, lx, m, x << 1); } int get(int l, int r, int lx = 0, int rx = N, int x = 1){ if(lx > r || rx < l) return -1; if(lx >= l && rx <= r) return mx[x]; int m = (lx + rx) >> 1; return max(get(l, r, lx, m, x<<1), get(l, r, m+1, rx, x<<1|1)); } }tree; void init(int n, vector<int> H){ for(int i=0;i<n;i++){ h[i] = H[i]; pos[h[i]] = i; } vector<int> ss; for(int i=0;i<n;i++){ while(!ss.empty() && h[ss.back()] < h[i]) ss.pop_back(); if(!ss.empty()) lx[i] = ss.back(); else lx[i] = n; ss.push_back(i); } ss.clear(); for(int i=n-1;~i;i--){ while(!ss.empty() && h[ss.back()] < h[i]) ss.pop_back(); if(!ss.empty()) rx[i] = ss.back(); else rx[i] = n; ss.push_back(i); } ss.clear(); h[n] = N; tree.build(); for(int i=0;i<n;i++){ if(h[lx[i]] < h[rx[i]]){ swap(lx[i], rx[i]); } mn[i][0] = rx[i]; mx[i][0] = lx[i]; } mn[n][0] = mx[n][0] = n; //~ for(int i=0;i<n;i++) cout<<mn[i][0]<<" "; //~ cout<<"\n"; //~ for(int i=0;i<n;i++) cout<<mx[i][0]<<" "; //~ cout<<"\n"; for(int j=1;j<lg;j++){ for(int i=0;i<=n;i++){ mn[i][j] = mn[mn[i][j-1]][j-1]; mx[i][j] = mx[mx[i][j-1]][j-1]; } } } int check(int a, int c){ int res = 0; for(int i=lg-1;~i;i--){ if(h[mx[a][i]] <= h[c]){ //~ cout<<mx[a][i]<<" "<<h[mx[a][i]]<<" "<<h[c]<<"\n"; //~ cout<<i<<"\n"; a = mx[a][i], res += (1 << i); } } for(int i=lg-1;~i;i--){ if(h[mn[a][i]] <= h[c]){ //~ cout<<mx[a][i]<<" "<<h[mx[a][i]]<<" "<<h[c]<<"\n"; a = mn[a][i], res += (1 << i); } } if(a != c) return N; return res; } int minimum_jumps(int a, int b, int c, int d) { //~ int l = max(a, tree.get_(a, b, h[c]) + 1); //~ if(l > b) return -1; //~ a = tree.get(l, b); //~ return check(pos[a], c); int res = N; for(int i=c;i<=d;i++){ int L = max(a, tree.get_(a, b, h[i]) + 1); if(L > b) continue; int mx = b; for(int j=b;j>=L;j--){ if(h[j] > h[mx]) mx = j; } res = min(res, check(mx, i)); //~ if(mx <= b) res = min(res, check(mx, i)); } if(res == N) return -1; return res; } /* 7 2 3 2 1 6 4 5 7 4 4 6 6 0 1 2 2 */
#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...