Submission #1111987

#TimeUsernameProblemLanguageResultExecution timeMemory
1111987onbertRoad Construction (JOI21_road_construction)C++17
38 / 100
10038 ms79908 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long const int maxn = 250005, inf = 2e9 + 10; const ll INF = 4e9 + 10; int n, k; pair<int, int> a[maxn]; int sz; vector<int> vals = {-inf}; int norm(ll x) {return min(max(x, -(ll)inf), (ll)inf);} int ldc(ll x) {return lower_bound(vals.begin(), vals.end(), x) - vals.begin();} int rdc(ll x) {return upper_bound(vals.begin(), vals.end(), x) - vals.begin() - 1;} struct node { int lpt, rpt, val; }; struct thing { ll id, dist, cnt; bool operator < (const thing &b) const { return dist > b.dist; } }; pair<ll, ll> b[maxn]; node seg[17931578]; int pt = 1; vector<int> lg = {1}; void build(int id, int l, int r) { seg[id] = {0, 0, 0}; if (l==r) return; int mid = (l+r) >> 1; seg[id].lpt = pt++; build(pt, l, mid); seg[id].rpt = pt++; build(pt, mid+1, r); } void update(int id, int l, int r, int target) { seg[id].val++; if (l==r) return; int mid = (l+r) >> 1; pt++; if (target<=mid) { seg[pt] = seg[seg[id].lpt]; seg[id].lpt = pt; update(pt, l, mid, target); } else { seg[pt] = seg[seg[id].rpt]; seg[id].rpt = pt; update(pt, mid+1, r, target); } } int qry(int id, int l, int r, int findl, int findr) { if (r<findl || findr<l) return 0; if (findl<=l && r<=findr) return seg[id].val; int mid = (l+r) >> 1; int lhs = qry(seg[id].lpt, l, mid, findl, findr); int rhs = qry(seg[id].rpt, mid+1, r, findl, findr); return lhs + rhs; } int cunt(ll id, ll dist) { int L = ldc(norm(a[id].second - dist)), R = rdc(norm(a[id].second + dist)); int val = qry(lg[id], 1, sz, L, R); int x = lower_bound(a+1, a+n+1, make_pair(norm(a[id].first - dist), -inf)) - a - 1; val -= qry(lg[x], 1, sz, L, R); return val; } priority_queue<thing> pq; signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> k; for (int i=1;i<=n;i++) { int x, y; cin >> x >> y; a[i] = {x+y, x-y}; vals.push_back(x-y); } sort(a+1, a+n+1); sort(vals.begin(), vals.end()); vals.erase(unique(vals.begin(), vals.end()), vals.end()); sz = vals.size() - 1; build(1, 1, sz); for (int i=1;i<=n;i++) { pt++; seg[pt] = seg[lg.back()]; lg.push_back(pt); update(pt, 1, sz, ldc(a[i].second)); } for (int i=2;i<=n;i++) { b[i] = {0, 1}; ll l = 1, r = INF; while (l < r) { ll mid = (l+r)/2; if (cunt(i, mid) == b[i].second) l = mid+1; else r = mid; } int x = cunt(i, l); pq.push({i, l, x}); // cout << i << " " << l << " " << cunt(i, l) << endl; } int total = 0; while (true) { ll id = pq.top().id, dist = pq.top().dist, cnt = pq.top().cnt; pq.pop(); // cout << id << " " << dist << " " << cnt << endl; for (;b[id].second<cnt;b[id].second++) { cout << dist << '\n'; total++; if (total == k) return 0; } if (b[id].second == id) continue; b[id].first = dist; ll l = dist+1, r = INF; while (l < r) { ll mid = (l+r) >> 1; if (cunt(id, mid) == b[id].second) l = mid+1; else r = mid; } int x = cunt(id, l); pq.push({id, l, x}); } }
#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...