This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |