제출 #1251711

#제출 시각아이디문제언어결과실행 시간메모리
1251711Zicrus장애물 (IOI25_obstacles)C++20
0 / 100
62 ms38704 KiB
#include <bits/stdc++.h> #include "obstacles.h" using namespace std; typedef long long ll; typedef pair<ll, ll> pll; #define all(v) v.begin(), v.end() constexpr ll inf = 1ll << 62ll; mt19937 mt(34056237); ll _ = 0; struct segment_tree { struct node { pll mn, mx; }; ll nt, n; vector<node> tree; segment_tree() { } segment_tree(ll n, vector<int> a) : n(n) { nt = 1; while (nt < n) nt *= 2; tree = vector<node>(2*nt, {{inf, 0}, {-inf, 0}}); for (ll i = 0; i < a.size(); i++) { tree[nt+i] = {{a[i], i}, {a[i], i}}; } for (ll i = nt-1; i > 0; i--) { tree[i].mn = min(tree[2*i].mn, tree[2*i+1].mn); tree[i].mx = max(tree[2*i].mx, tree[2*i+1].mx); } } pll range_min(ll k, ll tl, ll tr, ll l, ll r) { if (r < tl || l > tr) return {inf, -1}; if (l <= tl && r >= tr) return tree[k].mn; ll mid = tl + (tr - tl) / 2; return min(range_min(2*k, tl, mid, l, r), range_min(2*k+1, mid+1, tr, l, r)); } pll range_min(ll l, ll r) { return range_min(1, 0, nt-1, l, r); } pll range_max(ll k, ll tl, ll tr, ll l, ll r) { if (r < tl || l > tr) return {-inf, 0}; if (l <= tl && r >= tr) return tree[k].mx; ll mid = tl + (tr - tl) / 2; return max(range_max(2*k, tl, mid, l, r), range_max(2*k+1, mid+1, tr, l, r)); } pll range_max(ll l, ll r) { return range_max(1, 0, nt-1, l, r); } ll first_ge(ll k, ll tl, ll tr, ll l, ll v) { if (l > tr || tree[k].mx.first < v) return n; ll mid = tl + (tr - tl) / 2; ll res = first_ge(2*k, tl, mid, l, v); if (res < n) return res; return first_ge(2*k+1, mid+1, tr, l, v); } ll first_ge(ll l, ll v) { return first_ge(1, 0, nt-1, l, v); } ll first_le(ll k, ll tl, ll tr, ll l, ll v) { if (l > tr || tree[k].mn.first > v) return n; ll mid = tl + (tr - tl) / 2; ll res = first_le(2*k, tl, mid, l, v); if (res < n) return res; return first_le(2*k+1, mid+1, tr, l, v); } ll first_le(ll l, ll v) { return first_le(1, 0, nt-1, l, v); } ll last_ge(ll k, ll tl, ll tr, ll r, ll v) { if (tl > r || tree[k].mx.first < v) return -1; ll mid = tl + (tr - tl) / 2; ll res = last_ge(2*k+1, mid+1, tr, r, v); if (res >= 0) return res; return last_ge(2*k, tl, mid, r, v); } ll last_ge(ll r, ll v) { return last_ge(1, 0, nt-1, r, v); } ll last_le(ll k, ll tl, ll tr, ll r, ll v) { if (tl > r || tree[k].mn.first > v) return -1; ll mid = tl + (tr - tl) / 2; ll res = last_le(2*k+1, mid+1, tr, r, v); if (res >= 0) return res; return last_le(2*k, tl, mid, r, v); } ll last_le(ll r, ll v) { return last_le(1, 0, nt-1, r, v); } }; vector<int> T, H; segment_tree tree_T, tree_H; void initialize(vector<int> _T, vector<int> _H) { T = _T; H = _H; ll n = T.size(), m = H.size(); tree_T = segment_tree(n, T); tree_H = segment_tree(m, H); } pll find_best(ll s) { ll n = T.size(), m = H.size(); auto safe = [&](ll i, ll j) -> bool { return T[i] > H[j]; }; ll i = 0, j = s; auto improve_i = [&]() -> bool { // maximize T ll mn_i = tree_T.last_le(i, H[j]) + 1; ll mx_i = tree_T.first_le(i, H[j]) - 1; return false; auto [val, pos] = tree_T.range_max(mn_i, mx_i); if (val <= T[i]) return false; i = pos; return true; }; auto improve_j = [&]() -> bool { // minimize H ll mn_j = tree_H.last_ge(j, T[i]) + 1; ll mx_j = tree_H.first_ge(j, T[i]) - 1; return false; auto [val, pos] = tree_H.range_min(mn_j, mx_j); if (val >= H[j]) return false; j = pos; return true; }; while (true) { bool improved = false; improved |= improve_i(); improved |= improve_j(); if (!improved) break; } // make unique for (ll k = i-1; k >= 0; k--) { //assert(T[k] <= T[i]); if (T[k] >= T[i]) i = k; } for (ll k = j-1; k >= 0; k--) { //assert(H[k] >= H[j]); if (H[k] <= H[j]) j = k; } return {i, j}; } bool can_reach(int L, int R, int S, int D) { pll s = find_best(S); pll d = find_best(D); return s == d; } #ifdef TEST #include "grader.cpp" #endif
#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...