Submission #386553

#TimeUsernameProblemLanguageResultExecution timeMemory
386553PurpleCrayonRoad Construction (JOI21_road_construction)C++17
100 / 100
9453 ms35820 KiB
#include <bits/stdc++.h>
using namespace std;

#define ar array
#define sz(v) int(v.size())
typedef long long ll;
const int MAXN = 2.5e5+10;

struct FT {
    int n, bit[MAXN];
    void init(int _n){ n = _n+1; memset(bit, 0, sizeof(bit)); }
    int qry(int idx) { int ret = 0; for (++idx; idx > 0; idx -= idx & -idx) ret += bit[idx]; return ret; }
    int qry(int l, int r) { return qry(r) - qry(l - 1); }
    void upd(int idx, int delta) { for (++idx; idx < n; idx += idx & -idx) bit[idx] += delta; }
} ft;

string to_str(ar<ll, 2> a){ return "(" + to_string(a[0]) + ", " + to_string(a[1]) + ")"; }

ll dist(ar<ll, 2> a, ar<ll, 2> b){
    return abs<ll>(a[0]-b[0]) + abs<ll>(a[1]-b[1]);
}

int n, k;
ar<ll, 2> a[MAXN], oa[MAXN];
ar<ll, 3> b[MAXN];
int cmp[MAXN];
map<ll, int> mp;

int main(){
    cin >> n >> k;
    for (int i = 0; i < n; i++) {
        cin >> a[i][0] >> a[i][1], b[i][0] = a[i][0]+a[i][1], b[i][1] = a[i][0]-a[i][1], b[i][2] = i;
        oa[i] = a[i];
    }

    sort(a, a+n), sort(b, b+n);

    for (int i = 0; i < n; i++) mp[b[i][1]]++;
    int cc=0;
    for (auto& it : mp) it.second=cc++;
    for (int i = 0; i < n; i++) cmp[i] = mp[b[i][1]];

    auto cnt = [&](ll x) -> ll { //rotate 90 degrees, now want to find the point in some square
        ft.init(n);
        
        ll ans=0;
        for (int i=0, j=i; i < n; i++){
            for (; j < n && b[j][0]-b[i][0] <= x; j++) 
                ft.upd(cmp[j], 1);

            const ll cl = b[i][1]-x, cr = b[i][1]+x;
    
            auto rit = mp.upper_bound(cr);
            if (rit != mp.begin()){
                rit = prev(rit);

                auto lit = mp.lower_bound(cl);
                if (lit != mp.end()){
                    ans += ft.qry(lit->second, rit->second);
                }
            }
            if (ans-(i+1) >= k) return ans-(i+1);
            ft.upd(cmp[i], -1);
        }
        return ans-n;
    };

    ll lo=-1, hi=1e18+10, mid=(lo+hi)/2;
    while (lo < mid && mid < hi) {
        if (cnt(mid) >= k) hi = mid;
        else lo = mid;
        mid = (lo+hi)/2;
    }

    vector<ll> ans{hi}; ans.reserve(k);
    
    set<pair<ll, int>> s;
    ll x=hi-1;
    for (int i=0, j=i; i < n; i++){
        assert(j >= i);
        for (; j < n && b[j][0]-b[i][0] <= x; j++) 
            s.insert({b[j][1], j});
        s.erase(s.find({b[i][1], i}));

        ll cl = b[i][1]-x, cr = b[i][1]+x;

        auto lit = s.lower_bound({cl, -1});
        while (lit != s.end() && lit->first <= cr) {
            int cv = lit->second;
            ll d = dist(oa[b[i][2]], oa[b[cv][2]]);

            //cerr << i << ' ' << cv << ' ' << to_str(b[i]) << ' ' << to_str(b[cv]) << endl;
            ans.push_back(d);
            lit = next(lit);
        }
    }

    sort(ans.begin(), ans.end());
    while (sz(ans) < k) ans.push_back(ans.back());

    for (auto& it : ans) cout << it << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...