Submission #1315544

#TimeUsernameProblemLanguageResultExecution timeMemory
1315544vlomaczkRoad Construction (JOI21_road_construction)C++20
0 / 100
10094 ms175228 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; typedef long long ll; using namespace std; template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; struct Point { int x, y; friend bool operator<(Point a, Point b) { return a.y < b.y; } }; struct Node { int sum; Node *l, *r; Node(int s=0, Node* l=nullptr, Node* r=nullptr) : sum(s), l(l), r(r) {} }; Node* build(int tl, int tr) { if (tl == tr) return new Node(0); int tm = (tl + tr) / 2; Node* L = build(tl, tm); Node* R = build(tm+1, tr); return new Node(0, L, R); } Node* update(Node* v, int tl, int tr, int pos, long long add) { if (tl == tr) { return new Node(v->sum + add, nullptr, nullptr); } int tm = (tl + tr) / 2; if (pos <= tm) { Node* newL = update(v->l, tl, tm, pos, add); return new Node(v->sum + add, newL, v->r); } else { Node* newR = update(v->r, tm+1, tr, pos, add); return new Node(v->sum + add, v->l, newR); } } long long query(Node* v, int tl, int tr, int l, int r) { if (!v || l > tr || r < tl) return 0; if (l <= tl && tr <= r) return v->sum; int tm = (tl + tr) / 2; return query(v->l, tl, tm, l, r) + query(v->r, tm+1, tr, l, r); } int M = 250'010; vector<int> cnt(M,1); int n; int inf = 2e9+5; vector<Point> pkt; vector<int> X, Y; vector<Node*> root(M); int base = 1<<18; int numer = 1; void init() { for(int i=0; i<n; ++i) X.push_back(pkt[i].x); sort(X.begin(), X.end()); for(int i=0; i<n; ++i) Y.push_back(pkt[i].y); for(int i=0; i<n; ++i) { int idx = lower_bound(X.begin(), X.end(), pkt[i].x) - X.begin(); root[numer] = update(root[numer-1], 0, base-1, idx, 1); ++numer; } } int amount(vector<int> &x, int l, int r) { return upper_bound(x.begin(), x.end(), r) - lower_bound(x.begin(), x.end(), l); } int kwadrat(int x, int y, int r) { int a = lower_bound(X.begin(), X.end(), x-r) - X.begin(); int b = upper_bound(X.begin(), X.end(), x+r) - X.begin() - 1; int left = lower_bound(Y.begin(), Y.end(), y-r) - Y.begin(); int right = upper_bound(Y.begin(), Y.end(), y+r) - Y.begin() - 1; return query(root[right+1], 0, base-1, a,b) - query(root[left],0,base-1,a,b); } int find_nxt(int i) { ll lo = 0; ll hi = 2e9; if(cnt[i]==n) return inf; while(lo < hi) { ll mid = (lo+hi)/2; if(kwadrat(pkt[i].x, pkt[i].y, mid) > cnt[i]) hi = mid; else lo = mid+1; } cnt[i]++; return lo; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int k; cin >> n >> k; pkt.resize(n); for(int i=0; i<n; ++i) { int x,y; cin >> x >> y; pkt[i] = {x+y,x-y}; } sort(pkt.begin(), pkt.end()); root[0] = build(0,base-1); init(); priority_queue<pair<int, int>> pq; for(int i=0; i<n; ++i) { pq.push({-find_nxt(i), i}); } for(int ile=0; ile<2*k; ++ile){ if(ile%2==0) cout << -pq.top().first << "\n"; int i =pq.top().second; pq.pop(); pq.push({-find_nxt(i), i}); } return 0; }
#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...