제출 #1083276

#제출 시각아이디문제언어결과실행 시간메모리
1083276Tymond밀림 점프 (APIO21_jumps)C++17
100 / 100
957 ms78816 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 jump[MAXK][MAXN]; int jumpP[MAXK][MAXN]; int jumpL[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; for(int i = 0; i < n; i++){ tab[i] = H[i]; } 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++){ pii skoki = {getMxL(i), getMxP(i)}; if(skoki.fi == -1 && skoki.se == -1){ jump[0][i] = -1; }else if(skoki.fi == -1){ jump[0][i] = skoki.se; }else if(skoki.se == -1){ jump[0][i] = skoki.fi; }else{ jump[0][i] = (tab[skoki.fi] > tab[skoki.se] ? skoki.fi : skoki.se); } } for(int j = 1; j < MAXK; j++){ for(int i = 0; i < n; i++){ if(jump[j - 1][i] == -1){ jump[j][i] = -1; continue; } jump[j][i] = jump[j - 1][jump[j - 1][i]]; } } for(int i = 0; i < n; i++){ jumpP[0][i] = getMxP(i); jumpL[0][i] = getMxL(i); } for(int j = 1; j < MAXK; j++){ for(int i = 0; i < n; i++){ if(jumpP[j - 1][i] != -1){ jumpP[j][i] = jumpP[j - 1][jumpP[j - 1][i]]; }else{ jumpP[j][i] = -1; } if(jumpL[j - 1][i] != -1){ jumpL[j][i] = jumpL[j - 1][jumpL[j - 1][i]]; }else{ jumpL[j][i] = -1; } } } } int minimum_jumps(int A, int B, int C, int D){ int akt = B; int ans = 0; for(int j = MAXK - 1; j >= 0; j--){ if(jumpL[j][akt] != -1 && jumpL[j][akt] >= A){ int nxt = jumpL[j][akt]; if(jumpP[0][nxt] != -1 && jumpP[0][nxt] <= D){ akt = nxt; } } } //cout << akt << '\n'; for(int j = MAXK - 1; j >= 0; j--){ if(jump[j][akt] != -1){ int nxt = jump[j][akt]; //cout << nxt << ' '; if(jumpP[0][nxt] < C && jumpP[0][nxt] != -1){ akt =nxt; ans += (1 << j); } } } // cout << '\n'; // cout << akt << '\n'; if(jumpP[0][akt] != -1 && jumpP[0][akt] < C && jumpP[0][jump[0][akt]] <= D && jumpP[0][jump[0][akt]] != -1){ ans++; akt = jump[0][akt]; } //cout << akt << '\n'; for(int i = MAXK - 1; i >= 0; i--){ if(jumpP[i][akt] != -1 && jumpP[i][akt] < C){ akt = jumpP[i][akt]; ans += (1 << i); } } // cout << akt << '\n'; if(akt >= C && akt <= D){ return ans; } ans++; akt = jumpP[0][akt]; if(akt >= C && akt <= D){ return ans; } 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...