제출 #1257184

#제출 시각아이디문제언어결과실행 시간메모리
1257184flashmt장애물 (IOI25_obstacles)C++20
100 / 100
282 ms87696 KiB
#include "obstacles.h" #include <bits/stdc++.h> #ifdef LOCAL #include "Debug.h" #else #define debug(...) 42 #endif using namespace std; vector<vector<pair<int, int>>> jumpLeft, jumpRight; vector<pair<int, int>> intervals; int maxLog; void initialize(vector<int> t, vector<int> h) { int n = size(t), m = size(h); vector<pair<int, int>> incT = {{t[0], 0}}; auto decT = incT; for (int i = 1; i < n; i++) { if (t[i] > incT.back().first) incT.push_back({t[i], i}); if (t[i] < decT.back().first) decT.push_back({t[i], i}); } vector<vector<pair<int, int>>> eventsAt(n + 1); for (int i = 0; i < m; i++) if (h[i] < t[0]) { int low = 0, high = size(decT) - 1, res = -1; while (low <= high) { int mid = (low + high) / 2; if (h[i] >= decT[mid].first) { res = mid; high = mid - 1; } else low = mid + 1; } int row = res < 0 ? n - 1 : decT[res].second - 1; eventsAt[row].push_back({1, i}); } else { int low = 0, high = size(incT) - 1, res = -1; while (low <= high) { int mid = (low + high) / 2; if (h[i] < incT[mid].first) { res = mid; high = mid - 1; } else low = mid + 1; } int row = res >= 0 ? incT[res].second : n; eventsAt[row].push_back({0, i}); } set<pair<int, int>> active = {{-1, 0}, {m, 0}}; vector<int> l(m), r(m); intervals.resize(m); for (int row = n; row >= 0; row--) { sort(rbegin(eventsAt[row]), rend(eventsAt[row])); for (auto [isGood, col] : eventsAt[row]) if (isGood) { auto it = active.lower_bound({col, 1}); auto [nextCol, isNextGood] = *it; auto [prevCol, isPrevGood] = *prev(it); active.insert({col, 1}); if (isNextGood && isPrevGood) { l[col] = prevCol; r[col] = nextCol; } else if (isNextGood) l[col] = r[col] = nextCol; else if (isPrevGood) l[col] = r[col] = prevCol; else l[col] = r[col] = col; intervals[col] = {prevCol, nextCol}; } else { active.insert({col, 0}); l[col] = r[col] = col; intervals[col] = {col, col}; } } maxLog = 32 - __builtin_clz(m); jumpLeft = jumpRight = vector<vector<pair<int, int>>>(maxLog, vector<pair<int, int>>(m)); for (int i = 0; i < m; i++) { jumpLeft[0][i] = {l[i], l[i]}; jumpRight[0][i] = {r[i], r[i]}; } for (int i = 1; i < maxLog; i++) for (int j = 0; j < m; j++) { auto [jj, bound] = jumpLeft[i - 1][j]; jumpLeft[i][j] = {jumpLeft[i - 1][jj].first, max(jumpLeft[i - 1][jj].second, bound)}; tie (jj, bound) = jumpRight[i - 1][j]; jumpRight[i][j] = {jumpRight[i - 1][jj].first, min(jumpRight[i - 1][jj].second, bound)}; } } bool can_reach(int L, int R, int from, int to) { if (from > to) swap(from, to); if (from + 1 == to) return 1; int x = from, y = to; for (int i = maxLog - 1; i >= 0; i--) { auto [xx, bound] = jumpRight[i][x]; if (L <= bound && bound <= R) x = xx; auto [yy, bound2] = jumpLeft[i][y]; if (L <= bound2 && bound2 <= R) y = yy; } return intervals[x].second >= to && intervals[y].first <= from; }
#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...