제출 #569773

#제출 시각아이디문제언어결과실행 시간메모리
569773Lobo밀림 점프 (APIO21_jumps)C++17
0 / 100
190 ms156116 KiB
#include "jumps.h" #include<bits/stdc++.h> using namespace std; const long long inf = (long long) 1e18 + 10; const int inf1 = (int) 1e9 + 10; #define dbl long double #define endl '\n' #define sc second #define fr first #define mp make_pair #define pb push_back #define all(x) x.begin(), x.end() const int maxn = 2e5+10; int n, h[maxn], nx[maxn][25], nxl[maxn][25], nxr[maxn][25]; pair<int,int> tr[8*maxn]; int f1[8*maxn], f2[8*maxn], bg[maxn], cnt = 0; int att(int no, int l, int r, int no1, int pos, int val) { if(no == 0) no = ++cnt; if(l > pos || r < pos) return no; if(l == r) { tr[no] = mp(val,l); return no; } int mid = (l+r)/2; if(pos <= mid) { //vai para esquerda f1[no] = att(f1[no],l,mid,f1[no1],pos,val); f2[no] = f2[no1]; } else { f2[no] = att(f2[no],mid+1,r,f2[no1],pos,val); f1[no] = f1[no1]; } tr[no] = max(tr[f1[no]],tr[f2[no]]); return no; } pair<int,int> qrrmx(int no, int l, int r, int L, int R) { if(l > R || r < L) return mp(0,0); if(l >= L && r <= R) return tr[no]; int mid = (l+r)/2; return max(qrrmx(f1[no],l,mid,L,R),qrrmx(f2[no],mid+1,r,L,R)); } void init(int N, vector<int> H) { n = N; vector<pair<int,int>> vec; for(int i = 1; i <= n; i++) { h[i] = H[i-1]; vec.pb(mp(h[i],i)); } sort(all(vec)); int ant = 0; for(auto X : vec) { ant = att(0,1,n,ant,X.sc,X.fr); bg[X.fr] = ant; } //os proximos da esquerda e direita de cada um e 0 se não tiver stack<pair<int,int>> stl; for(int i = 1; i <= n; i++) { while(stl.size() && stl.top().fr < h[i]) { stl.pop(); } if(stl.size()) nxl[i][0] = stl.top().sc; else nxl[i][0] = 0; stl.push(mp(h[i],i)); } stack<pair<int,int>> str; for(int i = n; i >= 1; i--) { while(str.size() && str.top().fr < h[i]) { str.pop(); } if(str.size()) nxr[i][0] = str.top().sc; else nxr[i][0] = 0; str.push(mp(h[i],i)); } //sei qual o proximo normal de cada um for(int i = 1; i <= n; i++) { if(nxr[i][0] == 0 || h[nxl[i][0]] > h[nxr[i][0]]) nx[i][0] = nxl[i][0]; else nx[i][0] = nxr[i][0]; // cout << i << " " << nx[i][0] << " " << nxl[i][0] << " " << nxr[i][0] << endl; } for(int pt = 1; pt <= 20; pt++) { for(int i = 1; i <= n; i++) { nx[i][pt] = nx[nx[i][pt-1]][pt-1]; } } for(int pt = 1; pt <= 20; pt++) { for(int i = 1; i <= n; i++) { nxl[i][pt] = nxl[nxl[i][pt-1]][pt-1]; } } for(int pt = 1; pt <= 20; pt++) { for(int i = 1; i <= n; i++) { nxr[i][pt] = nxr[nxr[i][pt-1]][pt-1]; } } } int minimum_jumps(int A, int B, int C, int D) { A++; B++; C++; D++; //ir do a para o c //pego o maior cara entre a e b < c //na vez do h[c] qual era o maior do intervalo // int s = qrrmx(bg[h[C]],1,n,A,B).sc; int s = 0; int mx = 0; for(int i = A; i <= B; i++) { if(h[i] < h[C] && h[i] > mx) { mx = h[i]; s = i; } } if(s == 0) return -1; int t = C; int ans = 0; for(int pt = 20; pt >= 0; pt--) { if(nx[s][pt] == 0 || h[nx[s][pt]] > h[t]) continue; ans+= (1<<pt); s = nx[s][pt]; } //vai so para a direita ate chegar no t for(int pt = 20; pt >= 0; pt--) { if(nxr[s][pt] == 0 || nxr[s][pt] > t) continue; ans+= (1<<pt); s = nxr[s][pt]; } if(s == t) return ans; else return -1; }
#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...