Submission #1083138

#TimeUsernameProblemLanguageResultExecution timeMemory
1083138TymondRainforest Jumps (APIO21_jumps)C++17
4 / 100
723 ms58172 KiB
#include <bits/stdc++.h> #include "jumps.h" using namespace std; using ll = long long; using ld = long double; #define fi first #define se second #define vi vector<int> #define vll vector<long long> #define pii pair<int, int> #define pll pair<long long, long long> #define pb push_back #define mp make_pair #define eb emplace_back #define all(x) (x).begin(), (x).end() #define sz(x) (int)(x).size() mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count()); inline int rand(int l,int r){return uniform_int_distribution<int>(l, r)(rng);} inline ll rand(ll l,ll r){return uniform_int_distribution<ll>(l, r)(rng64);} #ifdef DEBUG auto&operator<<(auto&o,pair<auto,auto>p){return o<<"("<<p.first<<", "<<p.second<<")";} auto operator<<(auto&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<","+!i++<<e;return o<<"}";} #define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X) #else #define debug(...){} #endif struct custom_hash { static uint64_t splitmix64(uint64_t x) { x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); } }; const int MAXN = 5e5 + 7; const int MAXK = 22; int lg[MAXN]; int mx[MAXK][MAXN]; int jumpL[MAXK][MAXN]; int jumpP[MAXK][MAXN]; int tab[MAXN]; int n; bool distCount = 0; int getMx(int l, int p){ if(p < l){ return 0; } return max(mx[lg[p - l + 1]][l], mx[lg[p - l + 1]][p - (1 << lg[p - l + 1]) + 1]); } int getMxP(int ind){ if(getMx(ind + 1, n - 1) <= tab[ind]){ return -1; } int l = ind + 1; int p = n - 1; int s; while(l < p){ s = (l + p) / 2; if(getMx(ind + 1, s) <= tab[ind]){ l = s + 1; }else{ p = s; } } return l; } int getMxL(int ind){ if(getMx(0, ind - 1) <= tab[ind]){ return -1; } int l = 0; int p = ind - 1; int s; while(l < p){ s = (l + p + 1) / 2; if(getMx(s, ind - 1) <= tab[ind]){ p = s - 1; }else{ l = s; } } return l; } void init(int N, vi H) { n = N; bool f = 1; for(int i = 0; i < n; i++){ tab[i] = H[i]; if(tab[i] != i + 1){ f = 0; } } if(f){ distCount = 1; return; } for(int i = 2; i < MAXN; i++){ lg[i] = lg[i / 2] + 1; } for(int i = 0; i < n; i++){ mx[0][i] = tab[i]; } for(int j = 1; j < MAXK; j++){ for(int i = 0; i < n; i++){ mx[j][i] = max(mx[j - 1][i], mx[j - 1][min(n - 1, i + (1 << (j - 1)))]); } } for(int i = 0; i < n; i++){ jumpL[0][i] = getMxL(i); jumpP[0][i] = getMxP(i); } for(int j = 1; j < MAXK; j++){ for(int i = 0; i < n; i++){ if(jumpL[j - 1][i] != -1){ jumpL[j][i] = jumpL[j - 1][jumpL[j - 1][i]]; }else{ jumpL[j][i] = -1; } if(jumpP[j - 1][i] != -1){ jumpP[j][i] = jumpP[j - 1][jumpP[j - 1][i]]; }else{ jumpP[j][i] = -1; } } } } int dist(int a, int b){ int ans = 1e9; int akt = a; int res = 0; for(int j = MAXK - 1; j >= 0; j--){ if(jumpP[j][akt] != -1 && jumpP[j][akt] < b){ akt = jumpP[j][akt]; res += (1 << j); } } res++; akt = jumpP[0][akt]; if(akt == b){ ans = res; } if(getMx(0, a - 1) > tab[a]){ res = 0; akt = a; int l = 0; int p = a - 1; int s; while(l < p){ s = (l + p) / 2; if(getMx(s, a - 1) <= tab[a]){ p = s - 1; }else if(getMx(s, a - 1) >= tab[b]){ l = s + 1; }else{ p = s; } } if(tab[l] > tab[a] && tab[l] < tab[b]){ for(int j = MAXK - 1; j >= 0; j--){ if(jumpL[j][akt] != -1 && jumpL[j][akt] > l){ akt = jumpL[j][akt]; res += (1 << j); } } res++; akt = jumpL[0][akt]; if(akt == l){ for(int j = MAXK - 1; j >= 0; j--){ if(jumpP[j][akt] != -1 && jumpP[j][akt] < b){ akt = jumpP[j][akt]; res += (1 << j); } } res++; akt = jumpP[0][akt]; if(akt == b){ ans = min(ans, res); } } } } if(ans == 1e9){ return -1; } return ans; } int minimum_jumps(int A, int B, int C, int D){ if(distCount){ return C - B; } if(getMx(B + 1, C - 1) >= getMx(C, D)){ return -1; } if(A == B && C == D){ return dist(A, C); } vi dist(n, 1e9); queue<int> q; vi vis(n, 0); for(int i = A; i <= B; i++){ vis[i] = 1; q.push(i); dist[i] = 0; } while(sz(q)){ int v = q.front(); q.pop(); int akt = getMxL(v); if(akt != -1 && !vis[akt]){ q.push(akt); vis[akt] = 1; dist[akt] = dist[v] + 1; } akt = getMxP(v); if(akt != -1 && !vis[akt]){ q.push(akt); vis[akt] = 1; dist[akt] = dist[v] + 1; } } int ans = 1e9; for(int i = C; i <= D; i++){ ans = min(ans, dist[i]); } if(ans == 1e9){ return -1; } return ans; }
#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...