Submission #420784

#TimeUsernameProblemLanguageResultExecution timeMemory
420784rama_pangIzvanzemaljci (COI21_izvanzemaljci)C++17
5 / 100
77 ms3908 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 MAX). vector<int> sortByX(N); vector<int> sortByY(N); iota(begin(sortByX), end(sortByX), 0); iota(begin(sortByY), end(sortByY), 0); sort(begin(sortByX), end(sortByX), [&](int i, int j) { return pair(X[i], Y[i]) < pair(X[j], Y[j]); }); sort(begin(sortByY), end(sortByY), [&](int i, int j) { return pair(Y[i], X[i]) < pair(Y[j], X[j]); }); vector<int> posInSortByX(N); vector<int> posInSortByY(N); for (int i = 0; i < N; i++) { posInSortByX[sortByX[i]] = i; posInSortByY[sortByY[i]] = i; } const auto CountingSort = [&](vector<int> &a, const vector<int> &sorted, const vector<int> &pos) { static vector<int> res(N); fill(begin(res), end(res), 0); for (auto i : a) { res[pos[i]] = 1; } a.clear(); for (int i = 0; i < N; i++) { if (res[i]) { a.emplace_back(sorted[i]); } } }; 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; if (!vert) { CountingSort(alive, sortByY, posInSortByY); } else { CountingSort(alive, sortByX, posInSortByX); } static vector<lint> prefMinX; prefMinX.resize(alive.size()); static vector<lint> prefMaxX; prefMaxX.resize(alive.size()); static vector<lint> prefMinY; prefMinY.resize(alive.size()); static vector<lint> prefMaxY; prefMaxY.resize(alive.size()); static vector<lint> suffMinX; suffMinX.resize(alive.size()); static vector<lint> suffMaxX; suffMaxX.resize(alive.size()); static vector<lint> suffMinY; suffMinY.resize(alive.size()); static vector<lint> suffMaxY; suffMaxY.resize(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]); }; static vector<int> pref, suff; pref.clear(); 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 SolveK3 = [&](int K, lint L) { // Configuration: |- // Configuration: -| // Configuration: -,- // Configuration: -`- // Configuration: | | // Configuration: = }; const auto Solve = [&](int K, lint L) { static vector<int> alive; if (K == 1) { ans.clear(); alive.resize(N); iota(begin(alive), end(alive), 0); return SolveK1(L, alive, 0); } else if (K == 2) { ans.clear(); alive.resize(N); iota(begin(alive), end(alive), 0); if (SolveK2(L, alive, 0, 0)) { return true; } ans.clear(); alive.resize(N); iota(begin(alive), end(alive), 0); if (SolveK2(L, alive, 1, 0)) { return true; } } else if (K == 3) { } else { assert(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:121:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  121 |       if (i < 0 || i >= alive.size()) return 0;
      |                    ~~^~~~~~~~~~~~~~~
izvanzemaljci.cpp: In lambda function:
izvanzemaljci.cpp:125:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  125 |       if (i < 0 || i >= alive.size()) return 0;
      |                    ~~^~~~~~~~~~~~~~~
izvanzemaljci.cpp: In lambda function:
izvanzemaljci.cpp:137:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  137 |       if (!(i + 1 == alive.size() ||
      |             ~~~~~~^~~~~~~~~~~~~~~
izvanzemaljci.cpp: In function 'int main()':
izvanzemaljci.cpp:203: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]
  203 |   while (ans.size() < K) {
      |          ~~~~~~~~~~~^~~
izvanzemaljci.cpp:152:14: warning: variable 'SolveK3' set but not used [-Wunused-but-set-variable]
  152 |   const auto SolveK3 = [&](int K, lint L) {
      |              ^~~~~~~
izvanzemaljci.cpp: In lambda function:
izvanzemaljci.cpp:188:3: warning: control reaches end of non-void function [-Wreturn-type]
  188 |   };
      |   ^
#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...