// O(N^2), but faster than raphael_slow.cpp: ~ N^2/64 operations due // to using a bitset. #include #include #include #include #include #include using namespace std; int find_kth(vector& remaining, int k) { int pos = 0; int seen = 0; for (int i = 0; i < remaining.size(); ++i) { // std::popcount() in C++20. const int count = __builtin_popcountll(remaining[i]); if (seen + count >= k) { int bit_i = 0; while (seen < k) { if (remaining[i] & (1ULL << bit_i)) { seen++; } pos++; bit_i++; } remaining[i] = remaining[i] ^ (1ULL << (bit_i - 1)); return pos - 1; } seen += count; pos += 64; } assert(false); } std::array, 2> pick_players(const std::array, 2> &choices) { std::array, 2> teams; int N = choices[0].size() * 2; vector remaining; int num_uint64s = (choices[0].size() * 2 + 63) / 64; for (int i = 0; i < num_uint64s; ++i) { remaining.push_back(-1); } for (int i = 0; i < choices[0].size(); ++i) { for (int team = 0; team <= 1; team++) { int player = find_kth(remaining, choices[team][i] + 1); teams[team].push_back(player); } } return teams; } int main() { int N; std::cin >> N; assert(N % 2 == 0); std::array, 2> choices; choices[0].reserve(N); choices[1].reserve(N); for (int i = 0; i < N; ++i) { int choice; std::cin >> choice; // In the problem statement, the indexes are 1-based. choices[i >= N / 2].push_back(choice - 1); } auto teams = pick_players(choices); for (const auto &team : teams) { for (int player : team) { // Players 0-based in the problem statement. std::cout << player + 1 << " "; } std::cout << std::endl; } }