#include <iostream>
#include <algorithm>
#include <utility>
#include <queue>
#include <cassert>
#include <deque>
#include <cstdlib>
typedef std::pair<std::size_t, std::size_t> solution_type;
typedef std::pair<std::size_t, std::size_t> range_type;
struct range_compare
{
bool operator()(const range_type& a, const range_type& b)
{
const std::size_t a_size = a.second - a.first;
const std::size_t b_size = b.second - b.first;
if (a_size < b_size)
return true;
if (a_size > b_size)
return false;
return a.first > b.first;
}
};
solution_type find_solution(std::size_t nSpaces, std::size_t nthPerson, std::size_t nthSpace)
{
assert(nSpaces > 0 && nthPerson <= nSpaces && nthSpace <= nSpaces);
std::priority_queue<range_type, std::deque<range_type>, range_compare> bench((range_compare()));
bench.emplace(1, nSpaces);
solution_type result( nthPerson == nSpaces ? nthPerson : 0, nthSpace == nSpaces ? nthSpace : 0);
unsigned i = 1;
while (!result.first || !result.second)
{
assert(!bench.empty());
const auto range = bench.top();
bench.pop();
const std::size_t range_size = range.second - range.first + 1;
const std::size_t middle = range.first + (range_size / 2) - (range_size % 2 ? 0 : 1);
if (middle == nthSpace)
result.second = i;
if (i++ == nthPerson)
result.first = middle;
if (range_size > 1)
{
if (range.first != middle)
bench.emplace(range.first, middle - 1);
bench.emplace(middle + 1, range.second);
}
}
return result;
}
std::vector<std::vector<unsigned>> test_bench =
{
{ 13, 5, 8, 14, 3, 15, 6, 9, 16, 1, 17, 7, 10, 18, 2, 11, 19, 4, 12, 20 },
{ 14, 6, 8, 15, 2, 9, 16, 4, 10, 17, 1, 18, 7, 11, 19, 3, 12, 20, 5, 13, 21}
};
void test(const std::vector<unsigned>& v, unsigned nthPerson, unsigned nthSpace)
{
auto solution = find_solution(v.size(), nthPerson, nthSpace);
std::size_t place = std::find(v.begin(), v.end(), nthPerson) - v.begin() + 1;
std::size_t person = v[nthSpace-1];
if (place != solution.first || person != solution.second)
{
std::cout << "Expected " << place << ", " << person << " for "
<< nthPerson << ", " << nthSpace ;
std::cout << "\n\tGot " << solution.first << ", " << solution.second << '\n';
std::exit(0);
}
}
void test()
{
for (unsigned i = 0; i < test_bench.size(); ++i)
for (unsigned j = 0; j < test_bench[i].size(); ++j)
for (unsigned k = 0; k < test_bench[i].size(); ++k)
test(test_bench[i], j+1, k+1);
std::cout << "Tests passed!\n";
}
int main()
{
test();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHF1ZXVlPgojaW5jbHVkZSA8Y2Fzc2VydD4KI2luY2x1ZGUgPGRlcXVlPgojaW5jbHVkZSA8Y3N0ZGxpYj4KCnR5cGVkZWYgc3RkOjpwYWlyPHN0ZDo6c2l6ZV90LCBzdGQ6OnNpemVfdD4gc29sdXRpb25fdHlwZTsKdHlwZWRlZiBzdGQ6OnBhaXI8c3RkOjpzaXplX3QsIHN0ZDo6c2l6ZV90PiByYW5nZV90eXBlOwoKc3RydWN0IHJhbmdlX2NvbXBhcmUKewogICAgYm9vbCBvcGVyYXRvcigpKGNvbnN0IHJhbmdlX3R5cGUmIGEsIGNvbnN0IHJhbmdlX3R5cGUmIGIpCiAgICB7CiAgICAgICAgY29uc3Qgc3RkOjpzaXplX3QgYV9zaXplID0gYS5zZWNvbmQgLSBhLmZpcnN0OwogICAgICAgIGNvbnN0IHN0ZDo6c2l6ZV90IGJfc2l6ZSA9IGIuc2Vjb25kIC0gYi5maXJzdDsKCiAgICAgICAgaWYgKGFfc2l6ZSA8IGJfc2l6ZSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIGlmIChhX3NpemUgPiBiX3NpemUpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgcmV0dXJuIGEuZmlyc3QgPiBiLmZpcnN0OwogICAgfQp9OwoKc29sdXRpb25fdHlwZSBmaW5kX3NvbHV0aW9uKHN0ZDo6c2l6ZV90IG5TcGFjZXMsIHN0ZDo6c2l6ZV90IG50aFBlcnNvbiwgc3RkOjpzaXplX3QgbnRoU3BhY2UpCnsKICAgIGFzc2VydChuU3BhY2VzID4gMCAmJiBudGhQZXJzb24gPD0gblNwYWNlcyAmJiBudGhTcGFjZSA8PSBuU3BhY2VzKTsKCiAgICBzdGQ6OnByaW9yaXR5X3F1ZXVlPHJhbmdlX3R5cGUsIHN0ZDo6ZGVxdWU8cmFuZ2VfdHlwZT4sIHJhbmdlX2NvbXBhcmU+IGJlbmNoKChyYW5nZV9jb21wYXJlKCkpKTsKICAgIGJlbmNoLmVtcGxhY2UoMSwgblNwYWNlcyk7CgogICAgc29sdXRpb25fdHlwZSByZXN1bHQoIG50aFBlcnNvbiA9PSBuU3BhY2VzID8gbnRoUGVyc29uIDogMCwgbnRoU3BhY2UgPT0gblNwYWNlcyA/IG50aFNwYWNlIDogMCk7CgogICAgdW5zaWduZWQgaSA9IDE7CiAgICB3aGlsZSAoIXJlc3VsdC5maXJzdCB8fCAhcmVzdWx0LnNlY29uZCkKICAgIHsKICAgICAgICBhc3NlcnQoIWJlbmNoLmVtcHR5KCkpOwoKICAgICAgICBjb25zdCBhdXRvIHJhbmdlID0gYmVuY2gudG9wKCk7CiAgICAgICAgYmVuY2gucG9wKCk7CgogICAgICAgIGNvbnN0IHN0ZDo6c2l6ZV90IHJhbmdlX3NpemUgPSByYW5nZS5zZWNvbmQgLSByYW5nZS5maXJzdCArIDE7CiAgICAgICAgY29uc3Qgc3RkOjpzaXplX3QgbWlkZGxlID0gcmFuZ2UuZmlyc3QgKyAocmFuZ2Vfc2l6ZSAvIDIpIC0gKHJhbmdlX3NpemUgJSAyID8gMCA6IDEpOwoKICAgICAgICBpZiAobWlkZGxlID09IG50aFNwYWNlKQogICAgICAgICAgICByZXN1bHQuc2Vjb25kID0gaTsKCiAgICAgICAgaWYgKGkrKyA9PSBudGhQZXJzb24pCiAgICAgICAgICAgIHJlc3VsdC5maXJzdCA9IG1pZGRsZTsKCiAgICAgICAgaWYgKHJhbmdlX3NpemUgPiAxKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHJhbmdlLmZpcnN0ICE9IG1pZGRsZSkKICAgICAgICAgICAgICAgIGJlbmNoLmVtcGxhY2UocmFuZ2UuZmlyc3QsIG1pZGRsZSAtIDEpOwoKICAgICAgICAgICAgYmVuY2guZW1wbGFjZShtaWRkbGUgKyAxLCByYW5nZS5zZWNvbmQpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgoKc3RkOjp2ZWN0b3I8c3RkOjp2ZWN0b3I8dW5zaWduZWQ+PiB0ZXN0X2JlbmNoID0KeyAKICAgIHsgMTMsIDUsIDgsIDE0LCAzLCAxNSwgNiwgOSwgMTYsIDEsIDE3LCA3LCAxMCwgMTgsIDIsIDExLCAxOSwgNCwgMTIsIDIwIH0sCiAgICB7IDE0LCA2LCA4LCAxNSwgMiwgOSwgMTYsIDQsIDEwLCAxNywgMSwgMTgsIDcsIDExLCAxOSwgMywgMTIsIDIwLCA1LCAxMywgMjF9Cn07CgoKdm9pZCB0ZXN0KGNvbnN0IHN0ZDo6dmVjdG9yPHVuc2lnbmVkPiYgdiwgdW5zaWduZWQgbnRoUGVyc29uLCB1bnNpZ25lZCBudGhTcGFjZSkKewogICAgYXV0byBzb2x1dGlvbiA9IGZpbmRfc29sdXRpb24odi5zaXplKCksIG50aFBlcnNvbiwgbnRoU3BhY2UpOwoKICAgIHN0ZDo6c2l6ZV90IHBsYWNlID0gc3RkOjpmaW5kKHYuYmVnaW4oKSwgdi5lbmQoKSwgbnRoUGVyc29uKSAtIHYuYmVnaW4oKSArIDE7CiAgICBzdGQ6OnNpemVfdCBwZXJzb24gPSB2W250aFNwYWNlLTFdOwoKICAgIGlmIChwbGFjZSAhPSBzb2x1dGlvbi5maXJzdCB8fCBwZXJzb24gIT0gc29sdXRpb24uc2Vjb25kKQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCAiRXhwZWN0ZWQgIiA8PCBwbGFjZSA8PCAiLCAiIDw8IHBlcnNvbiA8PCAiIGZvciAiIAogICAgICAgICAgICAgICAgICA8PCBudGhQZXJzb24gPDwgIiwgIiA8PCBudGhTcGFjZSA7CiAgICAgICAgc3RkOjpjb3V0IDw8ICJcblx0R290ICIgPDwgc29sdXRpb24uZmlyc3QgPDwgIiwgIiA8PCBzb2x1dGlvbi5zZWNvbmQgPDwgJ1xuJzsKCiAgICAgICAgc3RkOjpleGl0KDApOwogICAgfQp9Cgp2b2lkIHRlc3QoKQp7CiAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgdGVzdF9iZW5jaC5zaXplKCk7ICsraSkKICAgICAgICBmb3IgKHVuc2lnbmVkIGogPSAwOyBqIDwgdGVzdF9iZW5jaFtpXS5zaXplKCk7ICsraikKICAgICAgICAgICAgZm9yICh1bnNpZ25lZCBrID0gMDsgayA8IHRlc3RfYmVuY2hbaV0uc2l6ZSgpOyArK2spCiAgICAgICAgICAgICAgICB0ZXN0KHRlc3RfYmVuY2hbaV0sIGorMSwgaysxKTsKCiAgICBzdGQ6OmNvdXQgPDwgIlRlc3RzIHBhc3NlZCFcbiI7Cn0KCgppbnQgbWFpbigpCnsKICAgIHRlc3QoKTsKfQ==