Submission #980077

#TimeUsernameProblemLanguageResultExecution timeMemory
980077asdfgraceEvent Hopping (BOI22_events)C++17
25 / 100
1580 ms8656 KiB
#include <bits/stdc++.h> using namespace std; #define dbg(x) //x #define prt(x) dbg(cerr << x) #define pv(x) dbg(cerr << #x << " = " << x << '\n') #define pv2(x) dbg(cerr << #x << " = " << x.first << ',' << x.second << '\n') #define parr(x) dbg(prt(#x << " = { "); for (auto y : x) prt(y << ' '); prt("}\n");) #define parr2(x) dbg(prt(#x << " = { "); for (auto [y, z] : x) prt(y << ',' << z << " "); prt("}\n");) #define parr2d(x) dbg(prt(#x << ":\n"); for (auto arr : x) {parr(arr);} prt('\n')); #define parr2d2(x) dbg(prt(#x << ":\n"); for (auto arr : x) {parr2(arr);} prt('\n')); /* o(n^2): for (each event) add edge from this one to every range that contains it and basically you want to find the shortest path from i to j note - if e[i] = e[j], there will be cycles in the graph but these aren't that useful unless you want to jump directly from i to j so we will be dealing with a dag here so you wouldn't want to switch from anything with the same end so e[i] must strictly increase note that if no contained pairs and you do have a CONTIGIOUS range of indices that you can hop to next how to solve in n^2? precomputing answers? just get all the edges maybe run n dijkstra? is this different bc dag? for (cur node) for (next node) if (reachable) for (each node) dist[node][next] = min(dist[node][next], dist[node][cur] + 1) or maybe just run a dijkstra if you have all the edges and n <= 1000 and q <= 100 greedy? if you CANNOT reach the dest from here, you should go to the latest ending event so that it starts before the dest ends what about when does it end if it ends before the dest ends that's fine it has to end after the dest starts it cannot end after the dest ends NOTE: while we must have s[j] <= e[i] we don't have to maximize or minimize it then we want to pick the maximum possible e[j] <= e[d] so we can make like a pref max for end values based on start values have to be less than or equal to whatever but that won't factor in the "e[j] <= e[d]" but that's a good reformulation given max start, what is max e[j] <= e[d]? we should be able to do queries offline then so that for each query we make some new values valid */ struct SegTree { int n; vector<int> st; SegTree (int x) { n = x; st.resize(2 * n, 0); } void upd(int k, int x) { k += n; st[k] = x; for (k /= 2; k >= 1; k /= 2) { st[k] = max(st[k * 2], st[k * 2 + 1]); } } int quer(int l, int r) { l += n; r += n; int res = 0; while (r >= l && l >= 1) { if (l % 2 == 1) res = max(res, st[l++]); if (r % 2 == 0) res = max(res, st[r--]); l /= 2; r /= 2; } return res; } }; int main() { ios::sync_with_stdio(0); cin.tie(0); int n, q; cin >> n >> q; vector<array<int, 3>> a(n); for (int i = 0; i < n; i++) { cin >> a[i][0] >> a[i][1]; a[i][2] = i; } sort(a.begin(), a.end(), [&] (array<int, 3> x, array<int, 3> y) { return x[1] < y[1]; }); vector<int> at(n); for (int i = 0; i < n; i++) { at[a[i][2]] = i; } vector<array<int, 3>> quer(q); for (int i = 0; i < q; i++) { cin >> quer[i][0] >> quer[i][1]; quer[i][0]--; quer[i][1]--; quer[i][0] = at[quer[i][0]]; quer[i][1] = at[quer[i][1]]; quer[i][2] = i; } sort(quer.begin(), quer.end(), [&] (array<int, 3> x, array<int, 3> y) { return x[1] < y[1]; }); parr2d(quer); vector<int> ans(q, -1); SegTree pmx(n); vector<int> s(n); for (int i = 0; i < n; i++) { s[i] = a[i][0]; } sort(s.begin(), s.end()); vector<int> ords(n); iota(ords.begin(), ords.end(), 0); sort(ords.begin(), ords.end(), [&] (int x, int y) { return a[x][0] < a[y][0]; }); vector<int> ats(n); for (int i = 0 ; i < n; i++) { ats[ords[i]] = i; } int j = 0; for (int i = 0; i < q; i++) { if (a[quer[i][0]][1] > a[quer[i][1]][1]) continue; for (; j < n && a[j][1] <= a[quer[i][1]][1]; j++) { pmx.upd(ats[j], a[j][1]); } if (quer[i][0] == quer[i][1]) {ans[quer[i][2]] = 0; continue;} int rb = a[quer[i][0]][1], res = 0; while (rb < a[quer[i][1]][0]) { // if rb < a[quer[i][1]][0], then you can't go to whatever the end is int k = upper_bound(s.begin(), s.end(), rb) - s.begin() - 1; int mx = pmx.quer(0, k); if (mx == rb) { res = -2; break; } rb = mx; res++; } res++; ans[quer[i][2]] = res; } for (int i = 0; i < q; i++) { if (ans[i] == -1) { cout << "impossible\n"; } else { cout << ans[i] << '\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...