Submission #1032976

#TimeUsernameProblemLanguageResultExecution timeMemory
1032976NeroZeinRailway Trip 2 (JOI22_ho_t4)C++17
100 / 100
607 ms79044 KiB
#include "bits/stdc++.h" using namespace std; #ifdef Nero #include "Deb.h" #else #define debug(...) #endif const int LOG = 18; const int N = 1e5 + 5; struct segtree { struct node { int mn = 0, mx = 0; }; int n; vector<node> seg; void init (vector<int>& a) { n = (int) a.size(); seg.resize(2 * n - 1); build(0, 0, n - 1, a); } node combine(node lx, node rx) { node ret; ret.mn = min(lx.mn, rx.mn); ret.mx = max(lx.mx, rx.mx); return ret; } void build(int nd, int l, int r, vector<int>& a) { if (l == r) { seg[nd].mn = seg[nd].mx = a[l]; return; } int mid = (l + r) >> 1; int rs = nd + ((mid - l + 1) << 1); build(nd + 1, l, mid, a); build(rs, mid + 1, r, a); seg[nd] = combine(seg[nd + 1], seg[rs]); } node qry(int nd, int l, int r, int s, int e) { if (l >= s && r <= e) { return seg[nd]; } int mid = (l + r) >> 1; int rs = nd + ((mid - l + 1) << 1); if (mid >= e) { return qry(nd + 1, l, mid, s, e); } else { if (mid < s) { return qry(rs, mid + 1, r, s, e); } else { return combine(qry(nd + 1, l, mid, s, e), qry(rs, mid + 1, r, s, e)); } } } int get_min(int l, int r) { return qry(0, 0, n - 1, l, r).mn; } int get_max(int l, int r) { return qry(0, 0, n - 1, l, r).mx; } }; bool contain(int l, int r, int x) { return l <= x && x <= r; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k, m; cin >> n >> k >> m; vector<int> min_left_edge(n + 1); vector<int> max_right_edge(n + 1); for (int i = 1; i <= n; ++i) { min_left_edge[i] = max_right_edge[i] = i; } for (int i = 0; i < m; ++i) { int u, v; cin >> u >> v; if (u > v) { min_left_edge[u] = min(min_left_edge[u], v); } else { max_right_edge[u] = max(max_right_edge[u], v); } } multiset<int> se; vector<vector<int>> max_right(LOG, vector<int>(n + 1)); for (int i = 1; i <= n; ++i) { if (i - k > 0) { se.erase(se.find(max_right_edge[i - k])); } se.insert(max_right_edge[i]); max_right[0][i] = *se.rbegin(); } se.clear(); vector<vector<int>> min_left(LOG, vector<int>(n + 1)); for (int i = n; i >= 1; --i) { if (i + k <= n) { se.erase(se.find(min_left_edge[i + k])); } se.insert(min_left_edge[i]); min_left[0][i] = *se.begin(); //debug(i, min_left[0][i]); } vector<segtree> rmn(LOG), rmx(LOG); rmn[0].init(min_left[0]); rmx[0].init(max_right[0]); for (int j = 1; j < LOG; ++j) { for (int i = 1; i <= n; ++i) { int l = min_left[j - 1][i], r = max_right[j - 1][i]; if (l > r) { min_left[j][i] = l; max_right[j][i] = r; } else { min_left[j][i] = rmn[j - 1].get_min(l, r); max_right[j][i] = rmx[j - 1].get_max(l, r); } } rmn[j].init(min_left[j]); rmx[j].init(max_right[j]); } int q; cin >> q; while (q--) { int s, t; cin >> s >> t; int l = s, r = s; int ans = 0; for (int j = LOG - 1; j >= 0; --j) { int nl = rmn[j].get_min(l, r); int nr = rmx[j].get_max(l, r); //debug(l, r, nl, nr); if (!contain(nl, nr, t)) { ans += 1 << j; l = nl; r = nr; } } if (ans == (1 << LOG) - 1) { cout << -1 << '\n'; } else { cout << ans + 1 << '\n'; } } return 0; }
#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...