제출 #948962

#제출 시각아이디문제언어결과실행 시간메모리
948962vladiliusBitaro's travel (JOI23_travel)C++17
0 / 100
3085 ms76776 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define int ll vector<vector<int>> sp1, sp2; vector<int> lg; int get1(int l, int r){ int k = lg[r - l + 1]; return max(sp1[l][k], sp1[r - (1 << k) + 1][k]); } int get2(int l, int r){ int k = lg[r - l + 1]; return min(sp2[l][k], sp2[r - (1 << k) + 1][k]); } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n; cin>>n; vector<int> x(n + 2); for (int i = 1; i <= n; i++){ cin>>x[i]; } x[0] = x[1]; x[n + 1] = x[n]; int q; cin>>q; vector<int> :: iterator it; auto left = [&](int k) -> int{ if (k == x[n]) return n; it = upper_bound(x.begin() + 1, x.end(), k); return (int) (prev(it) - x.begin()); }; auto right = [&](int k) -> int{ it = lower_bound(x.begin() + 1, x.end(), k); return (int) (it - x.begin()); }; lg.resize(n + 1); for (int i = 2; i <= n; i++){ lg[i] = lg[i / 2] + 1; } sp1.resize(n + 1); sp2.resize(n + 1); for (int i = 1; i <= n; i++){ sp1[i].resize(lg[n] + 1); sp2[i].resize(lg[n] + 1); } for (int i = 1; i <= n; i++){ sp1[i][0] = 2 * x[i] - x[i - 1]; sp2[i][0] = 2 * x[i] - x[i + 1]; } for (int j = 1; j <= lg[n]; j++){ for (int i = 1; i + (1 << j) <= n + 1; i++){ sp1[i][j] = max(sp1[i][j - 1], sp1[i + (1 << (j - 1))][j - 1]); sp2[i][j] = min(sp2[i][j - 1], sp2[i + (1 << (j - 1))][j - 1]); } } while (q--){ int s; cin>>s; ll out = 0; int i = left(s), j = right(s); if (i < 2){ cout<<x[n] - s<<"\n"; continue; } if (j >= n){ cout<<(s - x[1])<<"\n"; continue; } if (s - x[i] <= x[j] - s){ out += (s - x[i]); s = x[i]; j = i; } else { out += (x[j] - s); s = x[j]; i = j; } while (i > 1 || j < n){ if (i == 1){ out += (x[n] - s); break; } if (j == n){ out += (s - x[1]); break; } int d1 = s - x[i - 1], d2 = x[j + 1] - s; if (d1 <= d2){ if (get1(2, i) <= x[j + 1]){ out += (s - x[1]); s = x[1]; i = 1; continue; } // max(k < i): x[k + 1] - x[k] > x[j + 1] - x[k + 1] // <-> 2 * x[k + 1] - x[k] > x[j + 1] // <-> sp1[k + 1] > x[j + 1] // sp1[k + 1][0], ... sp1[i][0] int l = 1, r = i - 1; while (l + 1 < r){ int m = (l + r) / 2; if (get1(m + 1, i) > x[j + 1]){ l = m; } else { r = m - 1; } } while (r > 1 && get1(r + 1, i) <= x[j + 1]) r--; r++; out += (s - x[r]); s = x[r]; i = r; } else { if (get2(j + 1, n - 1) > x[i - 1]){ out += (x[n] - s); s = x[n]; j = n; continue; } // min(k > j): x[k + 1] - x[k] >= x[k] - x[i - 1] // <-> 2 * x[k] - x[k + 1] <= x[i - 1] // <-> sp2[k][0] <= x[i - 1] // sp2[j + 1][0], ... sp2[k][0] int l = j + 1, r = n - 1; while (l + 1 < r){ int m = (l + r) / 2; if (get2(j + 1, m) <= x[i - 1]){ r = m; } else { l = m + 1; } } while (l <= n && get2(j + 1, l) > x[i - 1]) l++; l--; out += (x[l] - s); s = x[l]; j = l; } } cout<<out<<"\n"; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...