Submission #576686

#TimeUsernameProblemLanguageResultExecution timeMemory
576686InternetPerson10Event Hopping (BOI22_events)C++17
100 / 100
785 ms61152 KiB
#include <bits/stdc++.h> typedef long long ll; using namespace std; set<int> s; map<int, int> idx; map<pair<int, int>, int> toEvent; vector<pair<int, int>> p; vector<int> mini; vector<int> mo; int point[200001][20]; int getPoint(int y2, int mid) { for(int i = 0; i < 20; i++) { if(mid & (1 << i)) { y2 = point[y2][i]; } } return y2; } struct SegTree { int lx, rx; int val = 1e9, id = -1; SegTree *ls, *rs; SegTree(int l, int r) { lx = l; rx = r; if(rx - lx > 1) { int mid = (lx + rx) / 2; ls = new SegTree(lx, mid); rs = new SegTree(mid, rx); val = min(ls->val, rs->val); if(val == ls->val) id = ls->id; if(val == rs->val) id = rs->id; } else { val = mini[lx]; id = lx; } } pair<int, int> getMin(int l, int r) { if(l <= lx && rx <= r) return {val, id}; if(r <= lx || rx <= l) return {1e9, -1}; return min(ls->getMin(l, r), rs->getMin(l, r)); } }; vector<int> v; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, q; cin >> n >> q; int g = 1; while(g <= 2*n) g *= 2; p.resize(n+1); mo.resize(n); mini.resize(g, 1e9); for(int i = 0; i < n; i++) { cin >> p[i].first >> p[i].second; s.insert(p[i].first); s.insert(p[i].second); } for(int y : s) { idx[y] = idx.size(); } for(int i = 0; i < n; i++) { p[i].first = idx[p[i].first]; p[i].second = idx[p[i].second]; int x, y; tie(x, y) = p[i]; mini[y] = min(mini[y], x); toEvent[p[i]] = i; } for(int i = 0; i < n; i++) { mo[i] = toEvent[p[i]]; } pair<int, int> badP = {1e9, -1}; p[n] = badP; toEvent[badP] = n; SegTree st(0, g); for(int i = 0; i < n; i++) { point[i][0] = toEvent[st.getMin(p[i].first, p[i].second + 1)]; if(point[i][0] == i) point[i][0] = n; } for(int i = 0; i < 20; i++) { point[n][i] = n; } for(int i = 1; i < 20; i++) { for(int j = 0; j < n; j++) { point[j][i] = point[point[j][i-1]][i-1]; } } while(q--) { int x, y; cin >> x >> y; x--; y--; if(x == y) { cout << "0\n"; continue; } else if(p[x] == p[y]) { cout << "1\n"; continue; } x = mo[x]; y = mo[y]; int l = -1, r = n; while(l != r - 1) { int mid = (l + r + 1) / 2; int y2 = getPoint(y, mid); if(y2 == n) r = mid; else if(p[y2].first <= p[x].second) r = mid; else l = mid; } int y2 = getPoint(y, r); if(y2 == n || r == n) { cout << "impossible\n"; } else if(!(p[y2].first <= p[x].second && p[x].second <= p[y2].second)) { cout << "impossible\n"; } else { cout << r+1 << '\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...