Submission #701162

#TimeUsernameProblemLanguageResultExecution timeMemory
701162minhcoolRoad Construction (JOI21_road_construction)C++17
5 / 100
10088 ms720280 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]; int savee[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; } int cnt; ii point; vector<ii> u1[N], u2[N]; void prep(int id, int l, int r, int pos){ int posi = lower_bound(type1[id].begin(), type1[id].end(), -point.fi - point.se) - type1[id].begin(); u1[cnt].pb({id, posi}); posi = lower_bound(type2[id].begin(), type2[id].end(), -point.fi + point.se) - type2[id].begin(); u2[cnt].pb({id, posi}); //upd1(id, posi); //upd2(id, posi); if(l == r) return; int mid = (l + r) >> 1; if(pos <= mid) prep(id << 1, l, mid, pos); else prep(id << 1 | 1, mid + 1, r, pos); } /* void upd(int id, int l, int r, int pos){ //int posi = lower_bound(type1[id].begin(), type1[id].end(), -point.fi - point.se) - type1[id].begin(); //int posi = 1; upd1(id, posi); //posi = lower_bound(type2[id].begin(), type2[id].end(), -point.fi + point.se) - type2[id].begin(); upd2(id, posi); if(l == r) return; int mid = (l + r) >> 1; if(pos <= mid) upd(id << 1, l, mid, pos); else upd(id << 1 | 1, mid + 1, r, pos); }*/ int type, val; vector<int> g1[N], g2[N]; void prep2(int id, int l, int r, int L, int R){// <= val, return no of pairs if(l > R || r < L) return; if(l >= L && r <= R){ if(!type) g1[cnt].pb(id); else g2[cnt].pb(id); return; } int mid = (l + r) >> 1; prep2(id << 1, l, mid, L, R); prep2(id << 1 | 1, mid + 1, r, L, R); } 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; } int pluss; void gett(int id, int l, int r, int L, int R){ 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; // cout << "OKAY " << type1[id][posi] << " " << plus << "\n"; pq.push(type1[id][posi] + pluss); } 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] + pluss); } return; //return get2(id, pos); } } int mid = (l + r) >> 1; gett(id << 1, l, mid, L, R); gett(id << 1 | 1, mid + 1, r, L, R); } mt19937 rng(1); int rnd(int l, int r){ int temp = rng() % (r - l + 1); return abs(temp) + l; } void process(){ cin >> n >> k; //n = k = 100000; //set<ii> se; //while(se.size() < n) se.insert({rnd(-1e9, 1e9), rnd(-1e9, 1e9)}); /* int cntt = 0; for(auto it : se){ cntt++; a[cntt] = it; }*/ 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); //return; 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()); } //return; int l = 1, r = 4e9 + 5; int itr = 0; for(int i = 1; i <= n; i++) savee[i] = mp[a[i]]; for(int i = 1; i <= n; i++){ cnt++; point = a[i]; prep(1, 1, n, savee[i]); type = 0; prep2(1, 1, n, 1, savee[i]); type = 1; prep2(1, 1, n, savee[i] + 1, n); } 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 = savee[i]; // cout << pos << " "; val = mid - a[i].fi - a[i].se; //answer += get(1, 1, n, 1, pos); for(auto it : g1[i]){ int pos = upper_bound(type1[it].begin(), type1[it].end(), val) - type1[it].begin(); pos--; //cout << "OK " << id << " " << pos << " " << type1[id].size() << "\n"; answer += get1(it, pos); } val = mid - a[i].fi + a[i].se; for(auto it : g2[i]){ int pos = upper_bound(type2[it].begin(), type2[it].end(), val) - type2[it].begin(); pos--; //cout << "OK " << id << " " << pos << " " << type2[id].size() << "\n"; answer += get2(it, pos); } //answer += get(1, 1, n, pos + 1, n); //continue; //cout << answer << "\n"; //point = a[i]; if(n <= 1000){ for(auto it : u1[i]) upd1(it.fi, it.se); for(auto it : u2[i]) upd2(it.fi, it.se); } //upd(1, 1, n, pos); } //return; //cout << mid << " " << answer << "\n"; if(answer < k) l = mid + 1; else r = mid; // itr++; //if(itr == 1) return; } if(n > 1000) return; //cout << (double)clock() / (double)CLOCKS_PER_SEC << "\n"; //return; //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]]; type = 0, val = l - a[i].fi - a[i].se, pluss = a[i].fi + a[i].se; gett(1, 1, n, 1, pos); type = 1, val = l - a[i].fi + a[i].se, pluss = a[i].fi - a[i].se; gett(1, 1, n, pos + 1, n); for(auto it : u1[i]) upd1(it.fi, it.se); for(auto it : u2[i]) upd2(it.fi, it.se); //continue; //point = a[i]; //upd(1, 1, n, pos); } 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"; } //cout << (double)clock() / (double)CLOCKS_PER_SEC << "\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:53: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]
   53 |  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:65: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]
   65 |  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:132: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]
  132 |   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:144: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]
  144 |   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)':
road_construction.cpp:180: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]
  180 |     assert(posi < type2[id].size());
      |            ~~~~~^~~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'void process()':
road_construction.cpp:245: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]
  245 |    for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0;
      |                   ~~^~~~~~~~~~~~~~~~
road_construction.cpp:246: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]
  246 |    for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0;
      |                   ~~^~~~~~~~~~~~~~~~
road_construction.cpp:250:8: warning: unused variable 'pos' [-Wunused-variable]
  250 |    int pos = savee[i];
      |        ^~~
road_construction.cpp:290: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]
  290 |   for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0;
      |                  ~~^~~~~~~~~~~~~~~~
road_construction.cpp:291: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]
  291 |   for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0;
      |                  ~~^~~~~~~~~~~~~~~~
road_construction.cpp:309: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]
  309 |  while(pq.size() < k) pq.push(l);
      |        ~~~~~~~~~~^~~
road_construction.cpp:231:6: warning: unused variable 'itr' [-Wunused-variable]
  231 |  int itr = 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...