Submission #701129

#TimeUsernameProblemLanguageResultExecution timeMemory
701129minhcoolRoad Construction (JOI21_road_construction)C++17
5 / 100
10066 ms379412 KiB
#include<bits/stdc++.h> using namespace std; #define int long long #define fi first #define se second #define pb push_back typedef pair<int, int> ii; typedef pair<ii, int> iii; typedef pair<ii, ii> iiii; const int N = 3e5 + 5; const int oo = 1e18 + 7, mod = 1e9 + 7; int n, k; ii a[N], b[N]; map<ii, int> mp; // type1[id]: (-x - y), type2[id]: (-x + y) vector<int> x, y; vector<int> type1[N << 2], type2[N << 2]; vector<int> bit1[N << 2], bit2[N << 2]; void build(int id, int l, int r){ bit1[id].resize(r - l + 2), bit2[id].resize(r - l + 2); if(l == r){ type1[id].pb(-b[l].fi - b[l].se); type2[id].pb(-b[l].fi + b[l].se); return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); for(auto it : type1[id << 1]) type1[id].pb(it); for(auto it : type2[id << 1]) type2[id].pb(it); for(auto it : type1[id << 1 | 1]) type1[id].pb(it); for(auto it : type2[id << 1 | 1]) type2[id].pb(it); sort(type1[id].begin(), type1[id].end()); sort(type2[id].begin(), type2[id].end()); type1[id].resize(unique(type1[id].begin(), type1[id].end()) - type1[id].begin()); type2[id].resize(unique(type2[id].begin(), type2[id].end()) - type2[id].begin()); bit1[id].resize(type1[id].size() + 1); bit2[id].resize(type2[id].size() + 1); } void upd1(int id, int id2){ for(; id2 < bit1[id].size(); id2 += id2 & -id2) bit1[id][id2]++; } int get1(int id, int id2){ int ans = 0; for(; id2; id2 -= id2 & -id2){ ans += bit1[id][id2]; } return ans; } void upd2(int id, int id2){ for(; id2 < bit2[id].size(); id2 += id2 & -id2) bit2[id][id2]++; } int get2(int id, int id2){ int ans = 0; for(; id2; id2 -= id2 & -id2){ ans += bit2[id][id2]; } return ans; } void upd(int id, int l, int r, int pos, ii point){ //cout << id << " " << l << " " << r << "\n"; int posi = lower_bound(type1[id].begin(), type1[id].end(), -point.fi - point.se) - type1[id].begin(); /// cout << "A " << id << " " << posi << " " << point.fi << " " << point.se << "\n"; upd1(id, posi); posi = lower_bound(type2[id].begin(), type2[id].end(), -point.fi + point.se) - type2[id].begin(); assert(posi); // cout << "B " << id << " " << posi << " " << point.fi << " " << point.se << "\n"; upd2(id, posi); if(l == r) return; int mid = (l + r) >> 1; if(pos <= mid) upd(id << 1, l, mid, pos, point); else upd(id << 1 | 1, mid + 1, r, pos, point); } int get(int id, int l, int r, int L, int R, int type, int val){// <= val, return no of pairs if(l > R || r < L) return 0; if(l >= L && r <= R){ if(!type){ int pos = upper_bound(type1[id].begin(), type1[id].end(), val) - type1[id].begin(); pos--; //cout << "OK " << id << " " << pos << " " << type1[id].size() << "\n"; return get1(id, pos); } else{ int pos = upper_bound(type2[id].begin(), type2[id].end(), val) - type2[id].begin(); pos--; //cout << "OK " << id << " " << pos << " " << type2[id].size() << "\n"; return get2(id, pos); } } int mid = (l + r) >> 1; return get(id << 1, l, mid, L, R, type, val) + get(id << 1 | 1, mid + 1, r, L, R, type, val); } bool cmp(ii a, ii b){ return a.se < b.se; } priority_queue<int, vector<int>, greater<int>> pq; int find_mn1(int id, int value){ int answer = 0; for(int i = 19; i >= 0; i--){ if((answer + (1LL << i)) >= bit1[id].size()) continue; if(value > bit1[id][answer + (1LL << i)]){ value -= bit1[id][answer + (1LL << i)]; answer += (1LL << i); } } return answer + 1; } int find_mn2(int id, int value){ int answer = 0; for(int i = 19; i >= 0; i--){ if((answer + (1LL << i)) >= bit2[id].size()) continue; if(value > bit2[id][answer + (1LL << i)]){ value -= bit2[id][answer + (1LL << i)]; answer += (1LL << i); } } return answer + 1; } void gett(int id, int l, int r, int L, int R, int type, int val, int plus){ if(l > R || r < L) return; if(l >= L && r <= R){ if(!type){ int pos = upper_bound(type1[id].begin(), type1[id].end(), val) - type1[id].begin(); pos--; int tempo = get1(id, pos); //cout << tempo << "\n"; //return; for(int i = 1; i <= tempo; i++){ int posi = find_mn1(id, i); //continue; assert(posi < type1[id].size()); // cout << "OKAY " << type1[id][posi] << " " << plus << "\n"; pq.push(type1[id][posi] + plus); } return; //return get1(id, pos); } else{ int pos = upper_bound(type2[id].begin(), type2[id].end(), val) - type2[id].begin(); pos--; int tempo = get2(id, pos); //return; for(int i = 1; i <= tempo; i++){ int posi = find_mn2(id, i); assert(posi < type2[id].size()); // cout << "OKAY " << type1[id][posi] << " " << plus << "\n"; pq.push(type2[id][posi] + plus); } return; //return get2(id, pos); } } int mid = (l + r) >> 1; gett(id << 1, l, mid, L, R, type, val, plus); gett(id << 1 | 1, mid + 1, r, L, R, type, val, plus); } void process(){ cin >> n >> k; for(int i = 1; i <= n; i++){ cin >> a[i].fi >> a[i].se; b[i] = a[i]; x.pb(a[i].fi), y.pb(a[i].se); } sort(x.begin(), x.end()), sort(y.begin(), y.end()); x.resize(unique(x.begin(), x.end()) - x.begin()); y.resize(unique(y.begin(), y.end()) - y.begin()); sort(a + 1, a + n + 1); sort(b + 1, b + n + 1, cmp); for(int i = 1; i <= n; i++) mp[b[i]] = i; build(1, 1, n); for(int i = 1; i <= (n << 2); i++){ type1[i].pb(-oo), type2[i].pb(-oo); sort(type1[i].begin(), type1[i].end()); sort(type2[i].begin(), type2[i].end()); } int l = 1, r = 4e9 + 5; while(l < r){ int mid = (l + r) >> 1; for(int i = 1; i <= (n << 2); i++){ for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0; for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0; } int answer = 0; for(int i = 1; i <= n; i++){ int pos = mp[a[i]]; // cout << pos << " "; answer += get(1, 1, n, 1, pos, 0, mid - a[i].fi - a[i].se); answer += get(1, 1, n, pos + 1, n, 1, mid - a[i].fi + a[i].se); //continue; //cout << answer << "\n"; upd(1, 1, n, pos, a[i]); } //return; //cout << mid << " " << answer << "\n"; if(answer < k) l = mid + 1; else r = mid; } //cout << l << "\n"; l--; for(int i = 1; i <= (n << 2); i++){ for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0; for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0; } for(int i = 1; i <= n; i++){ int pos = mp[a[i]]; gett(1, 1, n, 1, pos, 0, l - a[i].fi - a[i].se, a[i].fi + a[i].se); gett(1, 1, n, pos + 1, n, 1, l - a[i].fi + a[i].se, a[i].fi - a[i].se); //continue; upd(1, 1, n, pos, a[i]); } l++; //return; //cout << pq.size() << '\n'; //assert(pq.size() <= k); while(pq.size() < k) pq.push(l); for(int i = 1; i <= k; i++){ int x = pq.top(); pq.pop(); cout << x << "\n"; } } signed main(){ ios_base::sync_with_stdio(0); //freopen("road.inp", "r", stdin); //freopen("road.out", "w", stdout); cin.tie(0); process(); }

Compilation message (stderr)

road_construction.cpp: In function 'void upd1(long long int, long long int)':
road_construction.cpp:51:12: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   51 |  for(; id2 < bit1[id].size(); id2 += id2 & -id2) bit1[id][id2]++;
      |        ~~~~^~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'void upd2(long long int, long long int)':
road_construction.cpp:63:12: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   63 |  for(; id2 < bit2[id].size(); id2 += id2 & -id2) bit2[id][id2]++;
      |        ~~~~^~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'long long int find_mn1(long long int, long long int)':
road_construction.cpp:118:28: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  118 |   if((answer + (1LL << i)) >= bit1[id].size()) continue;
      |      ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'long long int find_mn2(long long int, long long int)':
road_construction.cpp:130:28: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  130 |   if((answer + (1LL << i)) >= bit2[id].size()) continue;
      |      ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/10/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:33,
                 from road_construction.cpp:1:
road_construction.cpp: In function 'void gett(long long int, long long int, long long int, long long int, long long int, long long int, long long int, long long int)':
road_construction.cpp:151:17: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  151 |     assert(posi < type1[id].size());
      |            ~~~~~^~~~~~~~~~~~~~~~~~
road_construction.cpp:165:17: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  165 |     assert(posi < type2[id].size());
      |            ~~~~~^~~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'void process()':
road_construction.cpp:201:21: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  201 |    for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0;
      |                   ~~^~~~~~~~~~~~~~~~
road_construction.cpp:202:21: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  202 |    for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0;
      |                   ~~^~~~~~~~~~~~~~~~
road_construction.cpp:222:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  222 |   for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0;
      |                  ~~^~~~~~~~~~~~~~~~
road_construction.cpp:223:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  223 |   for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0;
      |                  ~~^~~~~~~~~~~~~~~~
road_construction.cpp:236:18: warning: comparison of integer expressions of different signedness: 'std::priority_queue<long long int, std::vector<long long int>, std::greater<long long int> >::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  236 |  while(pq.size() < k) pq.push(l);
      |        ~~~~~~~~~~^~~
#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...