Submission #1354749

#TimeUsernameProblemLanguageResultExecution timeMemory
1354749retardeRoad Construction (JOI21_road_construction)C++20
100 / 100
5200 ms70032 KiB
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define int long long
#define all(x) (x).begin(), (x).end()

typedef long double ld;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<vector<int>> vvi;
typedef vector<vector<bool>> vvb;
typedef vector<vector<ll>> vvll;
typedef vector<string> vs;
typedef vector<vector<string>> vvs;
typedef vector<char> vc;
typedef vector<vector<char>> vvc;
typedef map<int, int> mii;
typedef unordered_map<int, int> umii;

const int mod = 1e9 + 7;
const int inf = INTMAX_MAX;
const bool tc = false;

int n, k;
const int mxn = 2e5 + 5;
map<int, vi> m;
vector<pair<int, vi>> a;

int dist(pii p1, pii p2) {
    pii ogp1 = {(p1.fi+p1.se)/2, (p1.fi-p1.se)/2};
    pii ogp2 = {(p2.fi+p2.se)/2, (p2.fi-p2.se)/2};
    return abs(ogp1.fi - ogp2.fi) + abs(ogp1.se - ogp2.se);
}

pair<bool, vi> ok(int mid) {
    // return true if cnt < k
    int l = 0, r = 0; set<pii> active; // this always contains active X range, sort by Y so i can find range
    vi dists;

    auto add = [&](int i) {
        // coluimn i
        for (auto &x : a[i].se) {
            active.insert({x, a[i].fi});
        }
    };

    auto remove = [&](int i) {
        // coluimn i
        for (auto &x : a[i].se) {
            active.erase({x, a[i].fi});
        }
    };

    for (int i = 0; i < (int)a.size(); i++) {
        // remove ls
        while (l < (int)a.size()) {
            if (a[i].fi - a[l].fi <= mid) break;
            remove(l); l++;
        }
        // add rs
        while (r < (int)a.size()) {
            if (a[r].fi - a[i].fi > mid) break;
            add(r); r++;
        }

        for (auto &x : a[i].se) {
            pii pt = {a[i].fi, x};
            int y = pt.se;
            auto it = active.lower_bound({y - mid, -1e18});
            while (it != active.end()) {
                pii cur = *it;
                swap(cur.fi, cur.se);
                if (pt == cur) {it++; continue;}
                if (cur.se > y + mid) break;
                dists.pb(dist(cur, pt));
                if (dists.size() > 2 * ((int)k)) return mp(false, dists);
                it++;
            }
        }
    }

    return mp(true, dists);
}

inline void solve() {
    cin >> n >> k;
    for (int i = 0; i < n; i++) {
        int x, y; cin >> x >> y;
        int u = x + y, v = x - y;
        m[u].pb(v);
    }

    for (auto &x : m) {
        sort(all(x.se));
        a.pb(x);
    }

    int lo = 0; int hi = 1e18;
    while (hi > lo + 1) {
        int mid = (lo + hi) / 2;
        // last one such that count(mid) < k
        pair<bool, vi> test = ok(mid);
        if (test.fi) lo = mid;
        else hi = mid;
    }   

    // lo
    vi v = ok(lo).se; sort(all(v));
    for (int i = 0; i < v.size(); i += 2) cout << v[i] << "\n";
    for (int i = 0; i < (2*k - (int)v.size())/2; i++) cout << hi << "\n";
}

void setIO(string s) {
    freopen((s + ".in").c_str(), "r", stdin);
    freopen((s + ".out").c_str(), "w", stdout);
}

signed main() {
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    //setIO();

    int t = 1;
    if (tc) {
        cin >> t;
    }

    while (t--) {
        solve();
    }
}

Compilation message (stderr)

road_construction.cpp: In function 'void setIO(std::string)':
road_construction.cpp:123:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  123 |     freopen((s + ".in").c_str(), "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
road_construction.cpp:124:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  124 |     freopen((s + ".out").c_str(), "w", stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...