Submission #420732

#TimeUsernameProblemLanguageResultExecution timeMemory
420732rama_pangIzvanzemaljci (COI21_izvanzemaljci)C++17
26 / 100
1375 ms12484 KiB
#include <bits/stdc++.h> using namespace std; using lint = long long; int main() { ios::sync_with_stdio(0); cin.tie(0); int N, K; cin >> N >> K; vector<lint> X(N), Y(N); for (int i = 0; i < N; i++) { cin >> X[i] >> Y[i]; } // There is a vertical or horizontal line which divides K = 3 -> {1, 2}. // Binary search the answer L. If cuts are shaped like (|-), then we // can greedily take big left part. If cuts are shaped like (| |), we // brute force middle (as we can greedily take middle), precompute left part // and right part. // // This takes O(N log N log MAX). vector<array<lint, 3>> ans; const auto SolveK1 = [&](lint L, vector<int> alive, int config) { if (alive.empty()) return true; lint minX = +2e9; lint maxX = -2e9; lint minY = +2e9; lint maxY = -2e9; for (auto i : alive) { minX = min(minX, X[i]); maxX = max(maxX, X[i]); minY = min(minY, Y[i]); maxY = max(maxY, Y[i]); } if (maxX - minX <= L && maxY - minY <= L) { lint len = max({1ll, maxX - minX, maxY - minY}); if (config == 0) ans.push_back({minX, minY, len}); if (config == 1) ans.push_back({maxX - len, minY, len}); if (config == 2) ans.push_back({maxX - len, maxY - len, len}); if (config == 3) ans.push_back({minX, maxY - len, len}); return true; } return false; }; const auto SolveK2 = [&](int L, vector<int> alive, int vert, int config) { if (alive.empty()) return true; sort(begin(alive), end(alive), [&](int i, int j) { if (!vert) { return pair(Y[i], X[i]) < pair(Y[j], X[j]); } else { return pair(X[i], Y[i]) < pair(X[j], Y[j]); } }); vector<lint> prefMinX(alive.size()); vector<lint> prefMaxX(alive.size()); vector<lint> prefMinY(alive.size()); vector<lint> prefMaxY(alive.size()); vector<lint> suffMinX(alive.size()); vector<lint> suffMaxX(alive.size()); vector<lint> suffMinY(alive.size()); vector<lint> suffMaxY(alive.size()); for (int i = 0; i < int(alive.size()); i++) { int id = alive[i]; prefMinX[i] = prefMaxX[i] = X[id]; prefMinY[i] = prefMaxY[i] = Y[id]; suffMinX[i] = suffMaxX[i] = X[id]; suffMinY[i] = suffMaxY[i] = Y[id]; } for (int i = 1; i < int(alive.size()); i++) { prefMinX[i] = min(prefMinX[i], prefMinX[i - 1]); prefMaxX[i] = max(prefMaxX[i], prefMaxX[i - 1]); prefMinY[i] = min(prefMinY[i], prefMinY[i - 1]); prefMaxY[i] = max(prefMaxY[i], prefMaxY[i - 1]); } for (int i = int(alive.size()) - 2; i >= 0; i--) { suffMinX[i] = min(suffMinX[i], suffMinX[i + 1]); suffMaxX[i] = max(suffMaxX[i], suffMaxX[i + 1]); suffMinY[i] = min(suffMinY[i], suffMinY[i + 1]); suffMaxY[i] = max(suffMaxY[i], suffMaxY[i + 1]); } const auto CalcPref = [&](int i) -> lint { if (i < 0 || i >= alive.size()) return 0; return max(prefMaxX[i] - prefMinX[i], prefMaxY[i] - prefMinY[i]); }; const auto CalcSuff = [&](int i) -> lint { if (i < 0 || i >= alive.size()) return 0; return max(suffMaxX[i] - suffMinX[i], suffMaxY[i] - suffMinY[i]); }; vector<int> pref; vector<int> suff = alive; reverse(begin(suff), end(suff)); for (int i = 0; i < int(alive.size()); i++) { pref.emplace_back(alive[i]); suff.pop_back(); if (!(i + 1 == alive.size() || (vert == 0 && Y[alive[i + 1]] != Y[alive[i]]) || (vert == 1 && X[alive[i + 1]] != X[alive[i]]))) { continue; } if (CalcPref(i) <= L && CalcSuff(i + 1) <= L) { assert(SolveK1(L, pref, 2)); assert(SolveK1(L, suff, 0)); return true; } } return false; }; const auto Solve = [&](int K, lint L) { vector<int> alive(N); iota(begin(alive), end(alive), 0); if (K == 1) { ans.clear(); return SolveK1(L, alive, 0); } else if (K == 2) { ans.clear(); if (SolveK2(L, alive, 0, 0)) { return true; } ans.clear(); if (SolveK2(L, alive, 1, 0)) { return true; } } return false; }; lint lo = 1; lint hi = 2e9; while (lo < hi) { lint md = (lo + hi) / 2; if (Solve(K, md)) { hi = md; } else { lo = md + 1; } } assert(Solve(K, lo)); int it = 0; while (ans.size() < K) { ans.push_back({lint(3e9 - 2 * it), lint(3e9), 1}); it++; } for (int i = 0; i < K; i++) { cout << ans[i][0] << ' ' << ans[i][1] << ' ' << ans[i][2] << '\n'; } return 0; }

Compilation message (stderr)

izvanzemaljci.cpp: In lambda function:
izvanzemaljci.cpp:92:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   92 |       if (i < 0 || i >= alive.size()) return 0;
      |                    ~~^~~~~~~~~~~~~~~
izvanzemaljci.cpp: In lambda function:
izvanzemaljci.cpp:96:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   96 |       if (i < 0 || i >= alive.size()) return 0;
      |                    ~~^~~~~~~~~~~~~~~
izvanzemaljci.cpp: In lambda function:
izvanzemaljci.cpp:107:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  107 |       if (!(i + 1 == alive.size() ||
      |             ~~~~~~^~~~~~~~~~~~~~~
izvanzemaljci.cpp: In function 'int main()':
izvanzemaljci.cpp:154:21: warning: comparison of integer expressions of different signedness: 'std::vector<std::array<long long int, 3> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  154 |   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...