제출 #1133888

#제출 시각아이디문제언어결과실행 시간메모리
1133888steveonalexRoad Construction (JOI21_road_construction)C++20
100 / 100
6277 ms126476 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define MASK(i) (1LL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) #define ALL(v) (v).begin(), (v).end() ll max(ll a, ll b){return (a > b) ? a : b;} ll min(ll a, ll b){return (a < b) ? a : b;} ll gcd(ll a, ll b){return __gcd(a, b);} ll LASTBIT(ll mask){return (mask) & (-mask);} int pop_cnt(ll mask){return __builtin_popcountll(mask);} int ctz(ll mask){return __builtin_ctzll(mask);} int logOf(ll mask){return __lg(mask);} mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);} template <class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b) {a = b; return true;} return false; } template <class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b) {a = b; return true;} return false; } template <class T> void printArr(T& container, string separator = " ", string finish = "\n"){ for(auto item: container) cout << item << separator; cout << finish; } template <class T> void remove_dup(vector<T> &a){ sort(ALL(a)); a.resize(unique(ALL(a)) - a.begin()); } struct FenwickTree{ int n; vector<ll> a; FenwickTree(int _n){ n = _n; a.resize(n+1); } void update(int i, ll v){ while(i <= n){ a[i] += v; i += LASTBIT(i); } } ll get(int i){ ll ans = 0; while(i > 0){ ans += a[i]; i -= LASTBIT(i); } return ans; } ll get(int l, int r){return get(r) - get(l-1);} int binary_lift(ll x){ int p = MASK(logOf(n)), idx =0; while(p > 0){ if (idx + p <= n && x > a[idx + p]){ idx += p; x -= a[idx]; } p >>= 1; } return idx + 1; } }; struct FakeSet{ priority_queue<int, vector<int>, greater<int>> pq, pending; void normalize(){ while(pq.size() && pending.size()){ int x = pq.top(), y = pending.top(); if (x == y){pq.pop(); pending.pop();} else break; } } void insert(int x){ pq.push(x); } void erase(int x){ pending.push(x); normalize(); } int top(){return pq.top();} int size(){return pq.size() - pending.size();} vector<int> get_set(){ vector<int> ans; while(size()){ ans.push_back(top()); erase(top()); } for(int i: ans) insert(i); return ans; } }; struct SegmentTree{ int n; vector<FakeSet> a; SegmentTree(int _n){ n = _n; for(int i = 0; i < n * 2 + 2; ++i) a.emplace_back(); } void update_add(int l, int r, int v){ l += n; r += n + 1; while(l < r){ if (l & 1) a[l++].insert(v); if (r & 1) a[--r].insert(v); l >>= 1; r >>= 1; } } void update_del(int l, int r, int v){ l += n; r += n + 1; while(l < r){ if (l & 1) a[l++].erase(v); if (r & 1) a[--r].erase(v); l >>= 1; r >>= 1; } } vector<int> get(int i){ i += n; vector<int> ans; while(i > 0){ vector<int> cur = a[i].get_set(); for(int j: cur) ans.push_back(j); i >>= 1; } return ans; } }; const ll INF = 1e12 + 69; ll man_dis(pair<ll, ll> a, pair<ll, ll> b){ return abs(a.first - b.first) + abs(a.second - b.second); } void solve(){ int n, k; cin >> n >> k; vector<pair<ll, ll>> a(n); for(int i = 0; i < n; ++i) cin >> a[i].first >> a[i].second; vector<pair<ll, ll>> b = a; for(auto &i: a){ i = make_pair(i.first + i.second, i.first - i.second); } vector<ll> X = {-INF}, Y = {-INF}; for(auto i: a){ X.push_back(i.first); Y.push_back(i.second); } remove_dup(X); remove_dup(Y); int x = X.size() - 1, y = Y.size() - 1; vector<vector<pair<int,int>>> query(x + 1); vector<vector<array<int, 3>>> add_query(x + 2), del_query(x + 2); for(int it = 0; it < n; ++it){ pair<int,int> i = a[it]; int idx1 = lower_bound(ALL(X), i.first) - X.begin(); int idx2 = lower_bound(ALL(Y), i.second) - Y.begin(); query[idx1].push_back({idx2, it}); } ll l = 0, r = 4e9; while(l < r){ ll mid = (l + r + 1) >> 1; for(int i = 0; i <= x + 1; ++i) { add_query[i].clear(); del_query[i].clear(); } for(int it = 0; it < n; ++it){ pair<ll, ll> i = a[it]; int L = lower_bound(ALL(Y), i.second - mid) - Y.begin(); int R = upper_bound(ALL(Y), i.second + mid) - Y.begin(); int idx = lower_bound(ALL(X), i.first - mid) - X.begin(); add_query[idx].push_back({{L, R, it}}); idx = upper_bound(ALL(X), i.first + mid) - X.begin(); del_query[idx].push_back({{L, R, it}}); } FenwickTree bit(y); ll tot = 0; for(int i = 1; i <= x; ++i){ for(auto j: add_query[i]){ bit.update(j[0], 1); bit.update(j[1], -1); } for(auto j: del_query[i]){ bit.update(j[0], -1); bit.update(j[1], 1); } for(pair<int, int> j: query[i]){ tot += bit.get(j.first); if (tot >= k * 2 + n) break; } if (tot >= k * 2 + n) break; } if (tot < k * 2 + n) l = mid; else r = mid - 1; } ll mid = l; for(int i = 0; i <= x + 1; ++i) { add_query[i].clear(); del_query[i].clear(); } for(int it = 0; it < n; ++it){ pair<int, int> i = a[it]; int L = lower_bound(ALL(Y), i.second - mid) - Y.begin(); int R = upper_bound(ALL(Y), i.second + mid) - Y.begin(); int idx = lower_bound(ALL(X), i.first - mid) - X.begin(); add_query[idx].push_back({{L, R, it}}); idx = upper_bound(ALL(X), i.first + mid) - X.begin(); del_query[idx].push_back({{L, R, it}}); } SegmentTree st(y); vector<ll> ans; for(int i = 1; i <= x; ++i){ for(auto j: add_query[i]){ st.update_add(j[0], j[1] - 1, j[2]); } for(auto j: del_query[i]){ st.update_del(j[0], j[1] - 1, j[2]); } for(pair<int, int> j: query[i]){ vector<int> cur = st.get(j.first); for(int k: cur) if (j.second < k) { ans.push_back(man_dis(b[j.second], b[k])); } } } sort(ALL(ans)); while(ans.size() < k) ans.push_back(mid + 1); printArr(ans, " ", "\n"); } int main(void){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); clock_t start = clock(); solve(); cerr << "Time elapsed: " << clock() - start << "ms!\n"; 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...