Submission #386558

#TimeUsernameProblemLanguageResultExecution timeMemory
386558PurpleCrayonEvent Hopping 2 (JOI21_event2)C++17
100 / 100
654 ms143284 KiB
#include <bits/stdc++.h> using namespace std; #define ar array #define sz(v) int(v.size()) typedef long long ll; const int MAXN = 1e5+10, INF = 1e9+10, MAXL = 20; struct T { int tl, tr; T *l=nullptr, *r=nullptr; int mx = -1; T(int _tl, int _tr): tl(_tl), tr(_tr) {} void extend(){ if (l||r||tl==tr) return; int tm=(tl+tr)/2; l = new T(tl, tm), r = new T(tm+1, tr); } void upd(int pos, int nv) { if (pos < tl || pos > tr) return; if (tl == tr){ mx = max(mx, nv); return; } extend(); l->upd(pos, nv), r->upd(pos, nv); mx = max(l->mx, r->mx); } int qry(int ql, int qr){ if (qr < tl || ql > tr) return -1; if (ql <= tl && tr <= qr) return mx; extend(); return max(l->qry(ql, qr), r->qry(ql, qr)); } } *t; int n, k, bst[MAXN], p[MAXN], anc[MAXN][MAXL]; ar<int, 3> a[MAXN], b[MAXN]; bool it(int w, int x, int y, int z){ return !(z <= w || y >= x); } int solve(vector<ar<int, 3>> v) { //run greedy int c=-1, ans=0; for (auto& r : v) if (r[0] >= c) ans++, c = r[1]; return ans; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin >> n >> k; for (int i = 0; i < n; i++) { ar<int, 3> _a; cin >> _a[0] >> _a[1], _a[2] = i; a[i] = _a; b[i] = _a; } sort(a, a+n, [&](auto i, auto j){ return i[1] < j[1]; }); { vector<ar<int, 3>> v; for (int i = 0; i < n; i++) v.push_back(a[i]); if (solve(v) < k){ cout << -1 << '\n'; return 0; } } memset(p, -1, sizeof(p)); sort(a, a+n); iota(bst, bst+n, 0); for (int i = n-1; i >= 0; i--){ int j = lower_bound(a, a+n, ar<int, 3>{a[i][1], -1, -1}) - a; if (j < n) p[a[i][2]] = a[bst[j]][2]; if (i < n-1 && a[bst[i+1]][1] < a[i][1]) bst[i] = bst[i+1]; } for (int i = 0; i < n; i++) { anc[i][0] = p[i]; } for (int j = 1; j < MAXL; j++) for (int i = 0; i < n; i++) anc[i][j] = (anc[i][j-1] == -1 ? -1 : anc[anc[i][j-1]][j-1]); auto qry = [&](int l, int r) -> int { //return the answer using only coords l <= i <= r int c = lower_bound(a, a+n, ar<int, 3>{l, -1, -1}) - a; if (c >= n) return 0; c = a[bst[c]][2]; int ans=1; auto good = [&](int i) -> bool { return l <= b[i][0] && b[i][1] <= r; }; if (!good(c)) return 0; for (int j = MAXL-1; j >= 0; j--) { if (anc[c][j] != -1 && good(anc[c][j])) ans += 1<<j, c = anc[c][j]; } return ans; }; set<int> loc{0, INF}; int loss = qry(0, INF)-k; t = new T(0, INF+1); vector<int> ans; for (int i = 0; i < n; i++) { if (sz(ans) >= k) break; int cl = b[i][0], cr = b[i][1]; bool bad=*loc.upper_bound(cl) < cr || t->qry(0, cl) >= cr; if (bad) continue; int pl = *prev(loc.upper_bound(cl)), pr = *loc.lower_bound(cr); int pans = qry(pl, pr); int cans = 1+qry(pl, cl)+qry(cr, pr); assert(cans <= pans); if (cans >= pans-loss){ ans.push_back(i); loc.insert(cl), loc.insert(cr); loss -= pans-cans; t->upd(cl, cr); } } assert(sz(ans) == k); for (int i : ans) cout << i+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...