Submission #392180

#TimeUsernameProblemLanguageResultExecution timeMemory
392180limabeansRoad Construction (JOI21_road_construction)C++17
100 / 100
3249 ms924900 KiB
#include <bits/stdc++.h> using namespace std; template<typename T> void out(T x) { cout << x << endl; exit(0); } #define watch(x) cout << (#x) << " is " << (x) << endl using ll = long long; const int maxn = 1e6 + 5; const ll inf = 1e18; struct psegtree { pair<ll,int> pr; //(xyval, idx) psegtree *left; psegtree *right; psegtree() : pr(inf, -1), left(), right() {} static psegtree init(int dep) { if (dep==0) { return {}; } else { psegtree *ch = new psegtree(init(dep-1)); return {ch, ch}; } } psegtree(psegtree *l, psegtree *r) { left = l; right = r; pr = min(l->pr, r->pr); } psegtree upd(int v, int tl, int tr, int i, ll val) { //cout<<tl<<","<<tr<<": "<<left<<" "<<right<<endl; if (tl==tr) { psegtree res; res.pr = {val, i}; return res; } else { int tm=(tl+tr)/2; if (i<=tm) { return {new psegtree(left->upd(2*v,tl,tm,i,val)), right}; } else { return {left, new psegtree(right->upd(2*v+1,tm+1,tr,i,val))}; } } } pair<ll,int> qryMin(int v, int tl, int tr, int l, int r) { if (l>tr || r<tl) { return {inf, -1}; } else if (l<=tl && tr<=r) { return pr; } else { int tm=(tl+tr)/2; return min(left->qryMin(2*v,tl,tm,l,r), right->qryMin(2*v+1,tm+1,tr,l,r)); } } }; struct pt { ll x,y; }; int n, k; pt a[maxn]; psegtree U[maxn], D[maxn]; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>k; for (int i=0; i<n; i++) { cin>>a[i].x>>a[i].y; } sort(a,a+n, [&](pt p, pt q) { return p.x<q.x; }); vector<pair<ll,int>> ord; ord.push_back({-inf,-1}); // (y,i) for (int i=0; i<n; i++) { ord.push_back({a[i].y,i}); } sort(ord.begin(), ord.end()); int N = (int)ord.size() - 1; auto get = [&](ll y, int i) { return lower_bound(ord.begin(), ord.end(), make_pair(y,i)) - ord.begin(); }; U[0] = psegtree::init(19); D[0] = psegtree::init(19); // sort pts by x // each psegtree to the left contains active pts with lower x // within the psegtree, stuff is sorted by y, with value being (-x+y) for (int i=0; i<n; i++) { int loc = get(a[i].y, i); U[i+1] = U[i].upd(1,1,N,loc,-a[i].x+a[i].y); D[i+1] = D[i].upd(1,1,N,loc,-a[i].x-a[i].y); } priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<pair<ll,int>>> pq; // (ans, idx) // i is 0-indexed auto push = [&](int i) { ll x = a[i].x; ll y = a[i].y; int loc = get(y, i); pair<ll,int> ures = U[i+1].qryMin(1,1,N,loc+1,N); pair<ll,int> dres = D[i+1].qryMin(1,1,N,1,loc-1); if (ures.first == inf && dres.first == inf) { return; } if (ures.first+x-y < dres.first+x+y) { pq.push({ures.first+x-y, i}); U[i+1] = U[i+1].upd(1,1,N,ures.second, inf); } else { pq.push({dres.first+x+y, i}); D[i+1] = D[i+1].upd(1,1,N,dres.second, inf); } }; for (int i=0; i<n; i++) { push(i); } for (int it=0; it<k; it++) { auto cur = pq.top(); pq.pop(); cout<<cur.first<<"\n"; push(cur.second); } 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...