Submission #744789

#TimeUsernameProblemLanguageResultExecution timeMemory
744789etheningRailway Trip 2 (JOI22_ho_t4)C++17
100 / 100
623 ms76596 KiB
#include "bits/stdc++.h" #include <valarray> using namespace std; using ll = long long; using pii = pair<int, int>; #define DEBUG 1 #define MULTI_TEST 0 struct Node { int l{}, r{}; Node() { this->l = 1e9, this->r = -1; } Node(int l, int r) { this->l = l, this->r = r; } Node(int x) { this->l = x, this->r = x; } Node operator+(const Node& other) { return Node(min(this->l, other.l), max(this->r, other.r)); } }; struct SegmentTree { vector<Node> leafs; vector<Node> node; void build(int n, vector<Node>& vec) { leafs = vec; node.resize(4 * n); auto build = [&](auto&& build, int id, int l, int r) -> void { if (l == r) node[id] = vec[l]; else { int mid = (l + r) / 2; build(build, id * 2, l, mid); build(build, id * 2 + 1, mid + 1, r); node[id] = node[id * 2] + node[id * 2 + 1]; } }; build(build, 1, 0, n - 1); } void update(int id, int l, int r, int pos, int val) { if (l == r) node[id] = val; else { int mid = (l + r) / 2; if (pos <= mid) update(id * 2, l, mid, pos, val); else update(id * 2 + 1, mid + 1, r, pos, val); } } Node query(int id, int l, int r, int L, int R) { if (l > R || r < L) return Node(); else if (L <= l && r <= R) return node[id]; else { int mid = (l + r) / 2; return query(id * 2, l, mid, L, R) + query(id * 2 + 1, mid + 1, r, L, R); } } }; int main() { cin.tie(0)->sync_with_stdio(0); int n, k; cin >> n >> k; int m; cin >> m; int lgn = 0; while (1 << (lgn + 1) <= n) { ++lgn; } ++lgn; ++lgn; vector<SegmentTree> segtree(lgn); vector<int> right_train(n, -1); vector<int> left_train(n, -1); for (int i = 0; i < m; i++) { int ai{}, bi{}; cin >> ai >> bi; --ai, --bi; if (bi > ai) { if (right_train[ai] == -1) right_train[ai] = bi; else right_train[ai] = max(right_train[ai], bi); } else { if (left_train[ai] == -1) left_train[ai] = bi; else left_train[ai] = min(left_train[ai], bi); } } vector<Node> initial_step(n); for (int i = 0; i < n; i++) initial_step[i] = Node(i); deque<pair<int, int>> Q; for (int i = 0; i < n; i++) { if (right_train[i] != -1) { while (!Q.empty() && right_train[i] > Q.back().second) Q.pop_back(); Q.push_back({i, right_train[i]}); } while (!Q.empty() && Q.front().first + k <= i) Q.pop_front(); while (!Q.empty() && Q.front().second <= i) Q.pop_front(); if (!Q.empty()) initial_step[i].r = Q.front().second; } Q.clear(); for (int i = n - 1; i >= 0; i--) { if (left_train[i] != -1) { while (!Q.empty() && left_train[i] < Q.back().second) Q.pop_back(); Q.push_back({i, left_train[i]}); } while (!Q.empty() && Q.front().first - k >= i) Q.pop_front(); while (!Q.empty() && Q.front().second >= i) Q.pop_front(); if (!Q.empty()) initial_step[i].l = Q.front().second; } segtree[0].build(n, initial_step); for (int i = 1; i < lgn; i++) { vector<Node> new_step(n); for (int j = 0; j < n; j++) { new_step[j] = segtree[i - 1].leafs[j]; new_step[j] = segtree[i - 1].query(1, 0, n - 1, new_step[j].l, new_step[j].r); } segtree[i].build(n, new_step); } // for (int i = 0; i < lgn; i++) { // cout << "Step " << (1 << i) << "\n"; // for (int j = 0; j < n; j++) { // cout << "Pos " << j << " : " << segtree[i].leafs[j].l << " " << segtree[i].leafs[j].r << endl; // } // } int q; cin >> q; for (int i = 0; i < q; i++) { int si{}, ti{}; cin >> si >> ti; --si, --ti; Node end_range = segtree[lgn - 1].leafs[si]; if (end_range.l > ti || end_range.r < ti) { cout << -1 << "\n"; continue; } int ans = 1 << (lgn - 1); int cur = 0; Node cur_range = {si, si}; for (int i = lgn - 1; i >= 0; i--) { Node new_range = segtree[i].query(1, 0, n - 1, cur_range.l, cur_range.r); if (new_range.l > ti || new_range.r < ti) { // not reach cur += 1 << i; cur_range = new_range; } else { // reach ans = min(ans, cur + (1 << i)); } } cout << ans << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...