Submission #393012

#TimeUsernameProblemLanguageResultExecution timeMemory
393012nvmdavaRoad Construction (JOI21_road_construction)C++17
13 / 100
5519 ms190228 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define ff first #define ss second mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int N = 1000005; const ll MOD = 1000000007; const ll INF = 0x3f3f3f3f3f3f3f3f; vector<pair<ll, int> > s, d; ll a[N], b[N]; int loc[N], w[N], rev[N]; int n; ll k; struct Node{ Node *le, *ri; int cnt = 0; int query(int l, int r, int L, int R){ if(l > R || r < L) return 0; if(L <= l && r <= R) return cnt; int m = (l + r) >> 1; return le -> query(l, m, L, R) + ri -> query(m + 1, r, L, R); } Node* update(int l, int r, int x){ if(l > x || r < x) return this; Node* ret = new Node(); if(l == r){ ret -> cnt = 1; return ret; } ret -> le = le; ret -> ri = ri; int m = (l + r) >> 1; ret -> le = ret -> le -> update(l, m, x); ret -> ri = ret -> ri -> update(m + 1, r, x); ret -> cnt = ret -> le -> cnt + ret -> ri -> cnt; return ret; } }; void buildd(Node* pnt, int l, int r){ if(l == r) return; int m = (l + r) >> 1; pnt -> le = new Node(); pnt -> ri = new Node(); buildd(pnt -> le, l, m); buildd(pnt -> ri, m + 1, r); } Node* tree[N]; vector<ll> ans; int l1[N], r1[N], l2[N], r2[N]; bool count(ll len){ ll cnt = 0; l1[0] = 1; r1[0] = 0; l2[0] = 1; r2[0] = 1; for(int i = 1; i <= n; ++i){ l1[i] = l1[i - 1]; while(a[l1[i]] < a[i] - len) ++l1[i]; r1[i] = i - 1; l2[i] = l2[i - 1]; while(b[l2[i]] < b[i] - len) ++l2[i]; r2[i] = r2[i - 1]; while(r2[i] + 1 <= n && b[r2[i] + 1] <= b[i] + len) ++r2[i]; } for(int i = n; i > 1; --i){ // int l1 = lower_bound(a + 1, a + i, a[i] - len) - a; // int r1 = i - 1; // int l2 = lower_bound(b + 1, b + rev[i], b[rev[i]] - len) - b; // int r2 = upper_bound(b + rev[i], b + n + 1, b[rev[i]] + len) - b - 1; if(l1[i] > r1[i] || l2[rev[i]] > r2[rev[i]]) continue; cnt += tree[r2[rev[i]]]->query(1, n, l1[i], r1[i]) - tree[l2[rev[i]] - 1]->query(1, n, l1[i], r1[i]); if(cnt >= k) return 0; } return 1; } void find(ll len){ set<pair<ll, int> > in; int l = 1; for(int i = 1; i <= n; ++i){ while(a[l] < a[i] - len){ in.erase({b[rev[l]], rev[l]}); ++l; } auto it = in.lower_bound({b[rev[i]] - len, 0}); while(it != in.end() && it -> ff <= b[rev[i]] + len){ ans.push_back(max(abs(b[rev[i]] - it -> ff), abs(a[i] - a[it -> ss]))); ++it; } in.insert({b[rev[i]], rev[i]}); } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n>>k; for(int x, y, i = 1; i <= n; ++i){ cin>>x>>y; s.push_back({x + y, i}); d.push_back({x - y, i}); } sort(s.begin(), s.end()); sort(d.begin(), d.end()); for(int i = 1; i <= n; ++i){ a[i] = s[i - 1].ff; loc[s[i - 1].ss] = i; } for(int i = 1; i <= n; ++i){ b[i] = d[i - 1].ff; w[i] = loc[d[i - 1].ss]; rev[w[i]] = i; } tree[0] = new Node(); buildd(tree[0], 1, n); for(int i = 1; i <= n; ++i) tree[i] = tree[i - 1] -> update(1, n, w[i]); ll len = 0; for(int i = 31; i >= 0; --i) if(count((1LL << i) | len)) len |= 1LL << i; find(len); sort(ans.begin(), ans.end()); ++len; while(ans.size() < k) ans.push_back(len); for(auto& x : ans) cout<<x<<'\n'; }

Compilation message (stderr)

road_construction.cpp: In function 'int main()':
road_construction.cpp:139:22: warning: comparison of integer expressions of different signedness: 'std::vector<long long int>::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  139 |     while(ans.size() < k)
      |           ~~~~~~~~~~~^~~
#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...