제출 #1254054

#제출 시각아이디문제언어결과실행 시간메모리
1254054jwvg0425장애물 (IOI25_obstacles)C++20
0 / 100
2095 ms12836 KiB
#include "obstacles.h" #include <stdio.h> #include <vector> #include <queue> #include <algorithm> #include <iostream> #include <string> #include <bitset> #include <map> #include <set> #include <tuple> #include <string.h> #include <math.h> #include <random> #include <functional> #include <assert.h> #include <math.h> #define all(x) (x).begin(), (x).end() #define xx first #define yy second using namespace std; template<typename T, typename Pr = less<T>> using pq = priority_queue<T, vector<T>, Pr>; using i64 = long long int; using ii = pair<int, int>; using ii64 = pair<i64, i64>; constexpr int clog2(int n) { return ((n < 2) ? 1 : 1 + clog2(n / 2)); } template<typename T> class SegmentTree { public: SegmentTree() = default; template<typename M> SegmentTree(const M& m) : merge(m) {} void init(const vector<T>& raw_) { raw = raw_; n = (int)raw.size(); int sz = (1 << (clog2(n) + 1)); data.resize(sz); _init(raw, 1, 0, n - 1); } T modify(int idx, function<T(T)> modifier) { return update(idx, modifier(raw[idx])); } T update(int idx, const T& newVal) { raw[idx] = newVal; return _update(1, 0, n - 1, idx, newVal); } T query(int left, int right) { return _query(1, 0, n - 1, left, right); } private: vector<T> raw; vector<T> data; int n; using Merge = function<T(const T&, const T&)>; Merge merge; T _init(const vector<T>& raw, int node, int start, int end) { int mid = (start + end) / 2; if (start == end) return data[node] = raw[start]; else return data[node] = merge(_init(raw, node * 2, start, mid), _init(raw, node * 2 + 1, mid + 1, end)); } T _update(int node, int start, int end, int index, const T& newVal) { if (index < start || index > end) return data[node]; if (start == end) data[node] = newVal; else { int mid = (start + end) / 2; data[node] = merge(_update(node * 2, start, mid, index, newVal), _update(node * 2 + 1, mid + 1, end, index, newVal)); } return data[node]; } T _query(int node, int start, int end, int left, int right) { if (left <= start && end <= right) return data[node]; int mid = (start + end) / 2; if (mid < left) return _query(node * 2 + 1, mid + 1, end, left, right); if (mid + 1 > right) return _query(node * 2, start, mid, left, right); return merge(_query(node * 2, start, mid, left, right), _query(node * 2 + 1, mid + 1, end, left, right)); } }; vector<int> t, h; vector<int> tmin; vector<int> tmax; SegmentTree<int> mtmax; vector<int> ot, mt; // ot = 잠기는 시점, mt = 이동 가능하게 되는 첫 시점 bool can_reach(int l, int r, int s, int d) { int target = min(ot[s] - 1, ot[d] - 1); int sl = s, sr = s; int dl = d, dr = d; int lo = 0, hi = s; while (lo <= hi) { int mid = (lo + hi) / 2; auto v = mtmax.query(mid, s); if (v > target) { lo = mid + 1; } else { sl = mid; hi = mid - 1; } } lo = 0; hi = d; while (lo <= hi) { int mid = (lo + hi) / 2; auto v = mtmax.query(mid, d); if (v > target) { lo = mid + 1; } else { dl = mid; hi = mid - 1; } } lo = s; hi = h.size() - 1; while (lo <= hi) { int mid = (lo + hi) / 2; auto v = mtmax.query(s, mid); if (v > target) { hi = mid - 1; } else { sr = mid; lo = mid + 1; } } lo = d; hi = h.size() - 1; while (lo <= hi) { int mid = (lo + hi) / 2; auto v = mtmax.query(d, mid); if (v > target) { hi = mid - 1; } else { dr = mid; lo = mid + 1; } } int lv = max(sl, dl); int rv = min(sr, dr); return lv <= rv; } void initialize(vector<int> T, vector<int> H) { t = T; tmin = T; tmax = T; for (int i = 1; i < T.size(); i++) tmin[i] = min(tmin[i - 1], t[i]); tmin.push_back(-1); for (int i = 1; i < T.size(); i++) tmax[i] = max(tmax[i - 1], t[i]); tmax.push_back(1987654321); h = H; ot.resize(h.size()); mt.resize(h.size()); for (int i = 0; i < h.size(); i++) { int lo = 0, hi = t.size(); while (lo <= hi) { int mid = (lo + hi) / 2; if (tmin[mid] <= h[i]) { ot[i] = mid; hi = mid - 1; } else { lo = mid + 1; } } } for (int i = 0; i < h.size(); i++) { int lo = 0, hi = t.size(); while (lo <= hi) { int mid = (lo + hi) / 2; if (tmax[mid] > h[i]) { mt[i] = mid; hi = mid - 1; } else { lo = mid + 1; } } } vector<ii> hsort; for (int i = 0; i < h.size(); i++) hsort.emplace_back(-h[i], i); // 크기 큰 것부터 순회 sort(all(hsort)); for (auto& [v, i] : hsort) { for (int c = 0; c < 3; c++) { if (i > 0 && mt[i - 1] < ot[i]) ot[i] = max(ot[i], ot[i - 1]); if (i + 1 < h.size() && mt[i + 1] < ot[i]) ot[i] = max(ot[i], ot[i + 1]); } } mtmax = SegmentTree<int>([](int l, int r) { return max(l, r); }); mtmax.init(mt); }
#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...