제출 #1149564

#제출 시각아이디문제언어결과실행 시간메모리
1149564Perl32Road Construction (JOI21_road_construction)C++20
0 / 100
10132 ms1285272 KiB
//I wrote this code 4 u <3
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

template<typename T> using normal_queue = priority_queue<T, vector<T>, greater<T>>;

template<typename T>
struct WT {
   vector<vector<int>> t, pref;
   vector<T> srt;
   int sz;

   WT() {}
   WT(vector<T>& a) {
      srt = a;
      ranges::sort(srt);
      srt.resize(unique(srt.begin(), srt.end()) - srt.begin());
      sz = 1;
      while (sz < (int) srt.size()) sz <<= 1;
      t.resize(sz << 1);
      pref.resize(sz << 1);
      t[1] = a;
      for (auto& x : t[1]) x = lower_bound(srt.begin(), srt.end(), x) - srt.begin();
      build(1, 0, srt.size());
   }

   void build(int x, int lx, int rx) {
      if (lx + 1 == rx) return;
      int m = (lx + rx) >> 1;
      pref[x].resize(t[x].size() + 1);
      for (int i = 0; i < (int) t[x].size(); ++i) {
         bool le = (t[x][i] < m);
         pref[x][i + 1] = pref[x][i] + le;
         if (le) {
            t[x << 1].push_back(t[x][i]);
         } else {
            t[x << 1 | 1].push_back(t[x][i]);
         }
      }
      build(x << 1, lx, m);
      build(x << 1 | 1, m, rx);
   }

   int le(int l, int r, int v, int x, int lx, int rx) {
      if (lx >= v) return 0;
      if (rx <= v) return r - l;
      int m = (lx + rx) >> 1, lb = pref[x][l], rb = pref[x][r];
      return le(lb, rb, v, x << 1, lx, m) + le(l - lb, r - rb, v, x << 1 | 1, m, rx);
   }

   int le(int l, int r, T v) { // counting elements lower than v in [l, r)
      v = lower_bound(srt.begin(), srt.end(), v) - srt.begin();
      return le(l, r, v, 1, 0, srt.size());
   }
};

struct Info {
    vector<int> x, y;
    WT<int> tt;

    Info() = default;
    Info(const vector<int>& _x, const vector<int>& _y) : x(_x), y(_y) {
        if (x.size()) tt = WT<int>(y);
    }

    int get(int lx, int ly, int rx, int ry) { // [lx, ly] : [rx, ry]
        lx = lower_bound(x.begin(), x.end(), lx) - x.begin();
        rx = upper_bound(x.begin(), x.end(), rx) - x.begin();
        return tt.le(lx, rx, ry + 1) - tt.le(lx, rx, ly);
    }
};

Info operator+(const Info& a, const Info& b) {
    vector<int> nx, ny;
    for (int l = 0, r = 0; l < (int) a.x.size() || r < (int) b.x.size();) {
        if (l < (int) a.x.size() && r < (int) b.x.size()) {
            if (pair{a.x[l], a.y[l]} < pair{b.x[r], b.y[r]}) {
                nx.push_back(a.x[l]);
                ny.push_back(a.y[l++]);
            } else {
                nx.push_back(b.x[r]);
                ny.push_back(b.y[r++]);
            }
        } else if (l < (int) a.x.size()) {
            nx.push_back(a.x[l]);
            ny.push_back(a.y[l++]);
        } else {
            nx.push_back(b.x[r]);
            ny.push_back(b.y[r++]);
        }
    }
    Info res(nx, ny);
    return res;
}

struct ST {
    vector<Info> t;
    int sz;

    ST(vector<pair<int, int>>& a) {
        sz = 1;
        while (sz < (int) a.size()) sz <<= 1;
        t.resize(sz << 1);
        for (int i = 0; i < (int) a.size(); ++i) t[i + sz] = Info({a[i].first}, {a[i].second});
        for (int i = sz - 1; i > 0; --i) {
            t[i] = t[i << 1] + t[i << 1 | 1];
        }
    }

    int get(int l, int r, int lx, int ly, int rx, int ry) {
        l += sz; r += sz;
        int res = 0;
        while (l < r) {
            if (l & 1) res += t[l++].get(lx, ly, rx, ry);
            if (r & 1) res += t[--r].get(lx, ly, rx, ry);
            l >>= 1; r >>= 1;
        }
        return res;
    }
};

const int inf = 0x3f3f3f3f;

signed main(int32_t argc, char *argv[]) {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, k;
    cin >> n >> k;
    vector<pair<int, int>> a(n);
    for (auto& c : a) {
        int x, y;
        cin >> x >> y;
        c = {x + y, x - y};
    }
    ST tt(a);
    auto counting = [&](int i, int m) {
        int lx = a[i].first - m, rx = a[i].first + m;
        int ly = a[i].second - m, ry = a[i].second + m;
        return tt.get(i, n, lx, ly, rx, ry);
    };
    vector<ll> cnt(n, 1);
    auto solve = [&](int i) {
        int lx = -1, rx = inf;
        while (lx + 1 < rx) {
            int m = (lx + rx) >> 1;
            if (counting(i, m) <= cnt[i]) {
                lx = m;
            } else {
                rx = m;
            }
        }
        return rx;
    };
    normal_queue<pair<int, int>> pq;
    for (int i = 0; i < n; ++i) pq.emplace(solve(i), i);
    while (k--) {
        auto [d, j] = pq.top(); pq.pop();
        cnt[j]++;
        cout << d << '\n';
        if (cnt[j] != n - j) pq.emplace(solve(j), j);
    }
}

/*

 */
#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...