#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <iterator>
#include <cassert>
using namespace std;
//Forward declarations:
template<typename Container> const typename Container::value_type&
getNthElement(const Container& container, size_t n);
template<typename Container> const typename Container::value_type&
getNthElementImpl(const Container& container, size_t n, random_access_iterator_tag);
template<typename Container> const typename Container::value_type&
getNthElementImpl(const Container& container, size_t n, forward_iterator_tag);
int main() {
assert(getNthElement(vector<int>{0, 1, 2, 3, 4}, 3) == 3);
assert(getNthElement(list<int>{0, 1, 2, 3, 4}, 3) == 3);
assert(getNthElement(deque<int>{0, 1, 2, 3, 4}, 3) == 3);
return 0;
}
template<typename Container> const typename Container::value_type&
getNthElement(const Container& container, size_t n) {
auto tag = typename iterator_traits<typename Container::iterator>::iterator_category{};
return getNthElementImpl(container, n, tag);
}
template<typename Container> const typename Container::value_type&
getNthElementImpl(const Container& container, size_t n, random_access_iterator_tag) {
cout << "O(1) implementation used" << endl;
auto iteratorToNthElement = begin(container) + n;
return *iteratorToNthElement;
}
template<typename Container> const typename Container::value_type&
getNthElementImpl(const Container& container, size_t n, forward_iterator_tag) {
cout << "O(N) implementation used" << endl;
auto itr = begin(container);
for (auto i = 0u; i < n; ++i) {
++itr;
}
return *itr;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bGlzdD4KI2luY2x1ZGUgPGRlcXVlPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxjYXNzZXJ0Pgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKLy9Gb3J3YXJkIGRlY2xhcmF0aW9uczoKdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPiBjb25zdCB0eXBlbmFtZSBDb250YWluZXI6OnZhbHVlX3R5cGUmCmdldE50aEVsZW1lbnQoY29uc3QgQ29udGFpbmVyJiBjb250YWluZXIsIHNpemVfdCBuKTsKdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPiBjb25zdCB0eXBlbmFtZSBDb250YWluZXI6OnZhbHVlX3R5cGUmCmdldE50aEVsZW1lbnRJbXBsKGNvbnN0IENvbnRhaW5lciYgY29udGFpbmVyLCBzaXplX3QgbiwgcmFuZG9tX2FjY2Vzc19pdGVyYXRvcl90YWcpOwp0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+IGNvbnN0IHR5cGVuYW1lIENvbnRhaW5lcjo6dmFsdWVfdHlwZSYKZ2V0TnRoRWxlbWVudEltcGwoY29uc3QgQ29udGFpbmVyJiBjb250YWluZXIsIHNpemVfdCBuLCBmb3J3YXJkX2l0ZXJhdG9yX3RhZyk7CgppbnQgbWFpbigpIHsKICBhc3NlcnQoZ2V0TnRoRWxlbWVudCh2ZWN0b3I8aW50PnswLCAxLCAyLCAzLCA0fSwgMykgPT0gMyk7CiAgYXNzZXJ0KGdldE50aEVsZW1lbnQobGlzdDxpbnQ+ezAsIDEsIDIsIDMsIDR9LCAzKSA9PSAzKTsKICBhc3NlcnQoZ2V0TnRoRWxlbWVudChkZXF1ZTxpbnQ+ezAsIDEsIDIsIDMsIDR9LCAzKSA9PSAzKTsKICByZXR1cm4gMDsKfQoKCnRlbXBsYXRlPHR5cGVuYW1lIENvbnRhaW5lcj4gY29uc3QgdHlwZW5hbWUgQ29udGFpbmVyOjp2YWx1ZV90eXBlJgpnZXROdGhFbGVtZW50KGNvbnN0IENvbnRhaW5lciYgY29udGFpbmVyLCBzaXplX3QgbikgewogIGF1dG8gdGFnID0gdHlwZW5hbWUgaXRlcmF0b3JfdHJhaXRzPHR5cGVuYW1lIENvbnRhaW5lcjo6aXRlcmF0b3I+OjppdGVyYXRvcl9jYXRlZ29yeXt9OwogIHJldHVybiBnZXROdGhFbGVtZW50SW1wbChjb250YWluZXIsIG4sIHRhZyk7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIENvbnRhaW5lcj4gY29uc3QgdHlwZW5hbWUgQ29udGFpbmVyOjp2YWx1ZV90eXBlJgpnZXROdGhFbGVtZW50SW1wbChjb25zdCBDb250YWluZXImIGNvbnRhaW5lciwgc2l6ZV90IG4sIHJhbmRvbV9hY2Nlc3NfaXRlcmF0b3JfdGFnKSB7CiAgY291dCA8PCAiTygxKSBpbXBsZW1lbnRhdGlvbiB1c2VkIiA8PCBlbmRsOwogIGF1dG8gaXRlcmF0b3JUb050aEVsZW1lbnQgPSBiZWdpbihjb250YWluZXIpICsgbjsKICByZXR1cm4gKml0ZXJhdG9yVG9OdGhFbGVtZW50Owp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+IGNvbnN0IHR5cGVuYW1lIENvbnRhaW5lcjo6dmFsdWVfdHlwZSYKZ2V0TnRoRWxlbWVudEltcGwoY29uc3QgQ29udGFpbmVyJiBjb250YWluZXIsIHNpemVfdCBuLCBmb3J3YXJkX2l0ZXJhdG9yX3RhZykgewogIGNvdXQgPDwgIk8oTikgaW1wbGVtZW50YXRpb24gdXNlZCIgPDwgZW5kbDsKICBhdXRvIGl0ciA9IGJlZ2luKGNvbnRhaW5lcik7CiAgZm9yIChhdXRvIGkgPSAwdTsgaSA8IG47ICsraSkgewogICAgKytpdHI7CiAgfQogIHJldHVybiAqaXRyOwp9Cg==