Submission #864283

#TimeUsernameProblemLanguageResultExecution timeMemory
864283danikoynovEvent Hopping (BOI22_events)C++14
100 / 100
295 ms23516 KiB
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; struct interval { int s, e, idx; }seg[maxn]; struct query { int start, finish, idx; }task[maxn]; bool cmp_finish(query q1, query q2) { return q1.finish < q2.finish; } int n, q; void input() { cin >> n >> q; for (int i = 1; i <= n; i ++) { cin >> seg[i].s >> seg[i].e; seg[i].idx = i; } for (int i = 1; i <= q; i ++) { cin >> task[i].start >> task[i].finish; task[i].idx = i; } } bool cmp_end(interval seg1, interval seg2) { return seg1.e < seg2.e; } int lf[maxn], rev[maxn], rf[maxn], ans[maxn]; map < int, int > fix; void build_graph() { sort(seg + 1, seg + n + 1, cmp_end); for (int i = 1; i <= n; i ++) { rev[seg[i].idx] = i; } for (int i = 1; i <= n; i ++) { int l = 1; int r = i; while(l <= r) { int m = (l + r) / 2; if (seg[m].e < seg[i].s) l = m + 1; else r = m - 1; } lf[i] = l; //while(seg[lf[i]].e < seg[i].s) // lf[i] ++; if (fix[seg[i].e] == 0) fix[seg[i].e] = lf[i]; else fix[seg[i].e] = min(fix[seg[i].e], lf[i]); } } const int maxlog = 21; int dp[maxlog][maxn]; int tree[4 * maxn]; void build_tree(int root, int left, int right) { if (left == right) { tree[root] = lf[left]; return; } int mid = (left + right) / 2; build_tree(root * 2, left, mid); build_tree(root * 2 + 1, mid + 1, right); tree[root] = min(tree[root * 2], tree[root * 2 + 1]); } int query_min(int root, int left, int right, int qleft, int qright) { //cout << root << " " << left << " " << right << " " << qleft << " " << qright << endl; //assert(root >= 0); if (qleft > right || qright < left) return 1e9; if (left >= qleft && right <= qright) return tree[root]; int mid = (left + right) / 2; return min(query_min(root * 2, left, mid, qleft, qright), query_min(root * 2 + 1, mid + 1, right, qleft, qright)); } void answer_queries() { for (int i = 1; i <= q; i ++) { task[i].start = rev[task[i].start]; task[i].finish = rev[task[i].finish]; } sort(task + 1, task + q + 1, cmp_finish); /**cout << "----------------------" << endl; for (int i = 1; i <= n; i ++) cout << seg[i].s << " :: " << seg[i].e << endl;*/ build_tree(1, 1, n); vector < int > viable; int pt = 1; for (int i = 1; i <= q; i ++) { int st = task[i].start, en = task[i].finish; while(pt <= en) { while(!viable.empty() && lf[viable.back()] >= lf[pt]) viable.pop_back(); int l = 0, r = (int)(viable.size()) - 1; while(l <= r) { int m = (l + r) / 2; if (viable[m] < lf[pt]) l = m + 1; else r = m - 1; } if (l >= viable.size()) dp[0][pt] = pt; else dp[0][pt] = viable[l]; for (int j = 1; j < maxlog; j ++) { dp[j][pt] = dp[j - 1][dp[j - 1][pt]]; } viable.push_back(pt); pt ++; } if (st == en) { ans[task[i].idx] = 0; continue; } if (seg[st].e == seg[en].e && st != en) { ans[task[i].idx] = 1; continue; } if (st > en) { ans[task[i].idx] = -1; continue; } if (st >= lf[en]) { ans[task[i].idx] = 1; continue; } int to = fix[seg[en].e]; to = min(to, query_min(1, 1, n, lf[en], en)); //for (int i = lf[en]; i <= en; i ++) // to = min(to, lf[i]); int steps = 1; bool done = false; int cur = viable.size() - 1; int l = 0, r = (int)(viable.size()) - 1; while(l <= r) { int m = (l + r) / 2; if (viable[m] >= to) r = m - 1; else l = m + 1; } cur = l; if (st >= to) { ans[task[i].idx] = 2; continue; } if (lf[viable[cur]] >= to) { ans[task[i].idx] = -1; continue; } steps ++; int jump = 0, ver = viable[cur]; if (st >= lf[ver]) { ans[task[i].idx] = steps + 1; continue; } ///cout << "here " << task[i].idx << endl; for (int bit = maxlog - 1; bit >= 0; bit --) { if (lf[dp[bit][ver]] > st) { ver = dp[bit][ver]; jump |= (1 << bit); } } jump ++; ver = dp[0][ver]; if (st >= lf[ver]) { ///cout << "HERE " << task[i].idx << endl; ans[task[i].idx] = steps + jump + 1; } else { ans[task[i].idx] = -1; } } for (int i = 1; i <= q; i ++) { if (ans[i] != - 1) cout << ans[i] << endl; else cout << "impossible" << endl; } } void solve() { input(); build_graph(); answer_queries(); } int main() { ///speed(); solve(); return 0; }

Compilation message (stderr)

events.cpp: In function 'void answer_queries()':
events.cpp:148:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  148 |             if (l >= viable.size())
      |                 ~~^~~~~~~~~~~~~~~~
events.cpp:193:14: warning: unused variable 'done' [-Wunused-variable]
  193 |         bool done = false;
      |              ^~~~
#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...