#include <iostream>
#include <type_traits>
#include <array>
namespace impl {
/// @brief Generates 0b1...1 with @tparam n ones
template <class T, unsigned n>
using n_ones = std::integral_constant<T, (~static_cast<T>(0) >> (sizeof(T) * 8 - n))>;
/// @brief Performs `@tparam input | (@tparam input << @tparam width` @tparam repeat times.
///@{
template <class T, T input, unsigned width, unsigned repeat>
struct lshift_add :
public lshift_add<T, lshift_add<T, input, width, 1>::value, width, repeat - 1> {
};
/// @brief Specialization for 1 repetition, just does the shift-and-add operation.
template <class T, T input, unsigned width>
struct lshift_add<T, input, width, 1> : public std::integral_constant<T,
(input & n_ones<T, width>::value) | (input << (width < sizeof(T) * 8 ? width : 0))> {
};
/// @brief Specialization for 0 repetitions (just in case).
template <class T, T input, unsigned width>
struct lshift_add<T, input, width, 0> :
public std::integral_constant<T, static_cast<T>(0)> {
};
///@}
/// @brief Recursively computes the integral log in base 2 of @tparam arg (as a constexpr).
///@{
template <unsigned arg>
struct log2 : public std::integral_constant<unsigned, log2<(arg >> 1)>::value + 1> {};
/// @brief Specialization for `arg=1` to interrupt recursion.
template <>
struct log2<1u> : public std::integral_constant<unsigned, 0u> {};
/// @brief The domain of log(x) is {x>0}
template <>
struct log2<0u> {};
///@}
/** @brief Generates the masks necessary for deinterleaving Morton numbers
* @tparam step 0-based index of the step; this corresponds to a rshift of
* `(@tparam dimensions - 1) * 2^@tparam step`.
* @tparam dimensions how many values are interleaved, default 2.
*
* This fills a T type with adjacent patterns of the type 0...01...1 where the number of ones is `2^@tparam step`
* and the total width is `@tparam dimensions * 2^@tparam step`; i.e. for `@tparam dimensions = 2`, we have
* 0. 0b...01010101
* 1. 0b...00110011
* 2. 0b...00001111
*/
template <class T, unsigned step, unsigned dimensions = 2u>
using mask = lshift_add<T, n_ones<T, 1 << step>::value, dimensions * (1 << step), sizeof(T) * 8 / (2 << step)>;
/** @brief Recursively defines a function that deinterleaves @tparam dimensions-dimensional Morton numbers.
* @note This extracts only the first bit. Rshift the argument once to get the next bit and so on.
* @tparam step Step of the deinterleave algorithm. Each of it corresponds to a rshift and a bitwise and with one of
* the masks defined in @see masks.
* @tparam dimensions Number of coordinates packed into the Morton number.
*/
///@{
template <class T, unsigned step, unsigned dimensions>
struct deinterleave {
static T work(T input) {
input = deinterleave<T, step - 1, dimensions>::work(input);
return (input | (input >> ((dimensions - 1) * (1 << (step - 1))))) & mask<T, step, dimensions>::value;
}
};
/// @brief Specialization for step 0, where there is just a bitwise and
template <class T, unsigned dimensions>
struct deinterleave<T, 0u, dimensions> {
static T work(T input) {
return input & mask<T, 0u, dimensions>::value;
}
};
///@}
/// @brief Helper constexpr which returns the number of steps needed to fully interleave a type @tparam T.
template <class T, unsigned dimensions>
using num_steps = std::integral_constant<unsigned, log2<sizeof(T) * 8 / dimensions>::value + 1>;
/// @brief Helper function which combines @see deinterleave and @see num_steps into a single call.
template <class T, unsigned dimensions>
T deinterleave_first(T n) {
return deinterleave<T, num_steps<T, dimensions>::value - 1, dimensions>::work(n);
}
/// @brief Helper class which recursively packs an array by de-interleaving one coordinate at a time
///@{
template <class T, unsigned dimensions, unsigned idx>
struct deinterleave_array {
static void work(T &n, std::array<T, dimensions> &tuple) {
std::get<idx>(tuple) = deinterleave_first<T, dimensions>(n);
deinterleave_array<T, dimensions, idx - 1>::work(n >>= 1, tuple);
}
};
/// @brief Specialization to stop the recursion.
template <class T, unsigned dimensions>
struct deinterleave_array<T, dimensions, 0> {
static void work(T &n, std::array<T, dimensions> &tuple) {
std::get<0>(tuple) = deinterleave_first<T, dimensions>(n);
}
};
///@}
}
/// @brief Extract the first coordinate from a Morton number
template <class T, unsigned dimensions = 2>
T deinterleave_one(T n) {
return impl::deinterleave_first<T, dimensions>(n);
}
/// @brief Extract @tparam dimensions coordinates from a Morton number
template <class T, unsigned dimensions = 2>
std::array<T, dimensions> deinterleave_all(T n) {
std::array<T, dimensions> retval;
impl::deinterleave_array<T, dimensions, dimensions - 1>::work(n, retval);
return retval;
}
int main() {
unsigned n = 0;
std::cin >> n;
std::array<unsigned, 2> coords = deinterleave_all(n);
std::cout << coords[0] << "\t" << coords[1] << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxhcnJheT4KCm5hbWVzcGFjZSBpbXBsIHsKICAgIC8vLyBAYnJpZWYgR2VuZXJhdGVzIDBiMS4uLjEgd2l0aCBAdHBhcmFtIG4gb25lcwogICAgdGVtcGxhdGUgPGNsYXNzIFQsIHVuc2lnbmVkIG4+CiAgICB1c2luZyBuX29uZXMgPSBzdGQ6OmludGVncmFsX2NvbnN0YW50PFQsICh+c3RhdGljX2Nhc3Q8VD4oMCkgPj4gKHNpemVvZihUKSAqIDggLSBuKSk+OwoKCiAgICAvLy8gQGJyaWVmIFBlcmZvcm1zIGBAdHBhcmFtIGlucHV0IHwgKEB0cGFyYW0gaW5wdXQgPDwgQHRwYXJhbSB3aWR0aGAgQHRwYXJhbSByZXBlYXQgdGltZXMuCiAgICAvLy9AewogICAgdGVtcGxhdGUgPGNsYXNzIFQsIFQgaW5wdXQsIHVuc2lnbmVkIHdpZHRoLCB1bnNpZ25lZCByZXBlYXQ+CiAgICBzdHJ1Y3QgbHNoaWZ0X2FkZCA6CiAgICAgICAgcHVibGljIGxzaGlmdF9hZGQ8VCwgbHNoaWZ0X2FkZDxULCBpbnB1dCwgd2lkdGgsIDE+Ojp2YWx1ZSwgd2lkdGgsIHJlcGVhdCAtIDE+IHsKICAgIH07CiAgICAvLy8gQGJyaWVmIFNwZWNpYWxpemF0aW9uIGZvciAxIHJlcGV0aXRpb24sIGp1c3QgZG9lcyB0aGUgc2hpZnQtYW5kLWFkZCBvcGVyYXRpb24uCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgVCBpbnB1dCwgdW5zaWduZWQgd2lkdGg+CiAgICBzdHJ1Y3QgbHNoaWZ0X2FkZDxULCBpbnB1dCwgd2lkdGgsIDE+IDogcHVibGljIHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8VCwKICAgICAgICAoaW5wdXQgJiBuX29uZXM8VCwgd2lkdGg+Ojp2YWx1ZSkgfCAoaW5wdXQgPDwgKHdpZHRoIDwgc2l6ZW9mKFQpICogOCA/IHdpZHRoIDogMCkpPiB7CiAgICB9OwogICAgLy8vIEBicmllZiBTcGVjaWFsaXphdGlvbiBmb3IgMCByZXBldGl0aW9ucyAoanVzdCBpbiBjYXNlKS4KICAgIHRlbXBsYXRlIDxjbGFzcyBULCBUIGlucHV0LCB1bnNpZ25lZCB3aWR0aD4KICAgIHN0cnVjdCBsc2hpZnRfYWRkPFQsIGlucHV0LCB3aWR0aCwgMD4gOgogICAgICAgIHB1YmxpYyBzdGQ6OmludGVncmFsX2NvbnN0YW50PFQsIHN0YXRpY19jYXN0PFQ+KDApPiB7CiAgICB9OwogICAgLy8vQH0KCgogICAgLy8vIEBicmllZiBSZWN1cnNpdmVseSBjb21wdXRlcyB0aGUgaW50ZWdyYWwgbG9nIGluIGJhc2UgMiBvZiBAdHBhcmFtIGFyZyAoYXMgYSBjb25zdGV4cHIpLgogICAgLy8vQHsKICAgIHRlbXBsYXRlIDx1bnNpZ25lZCBhcmc+CiAgICBzdHJ1Y3QgbG9nMiA6IHB1YmxpYyBzdGQ6OmludGVncmFsX2NvbnN0YW50PHVuc2lnbmVkLCBsb2cyPChhcmcgPj4gMSk+Ojp2YWx1ZSArIDE+IHt9OwogICAgLy8vIEBicmllZiBTcGVjaWFsaXphdGlvbiBmb3IgYGFyZz0xYCB0byBpbnRlcnJ1cHQgcmVjdXJzaW9uLgogICAgdGVtcGxhdGUgPD4KICAgIHN0cnVjdCBsb2cyPDF1PiA6IHB1YmxpYyBzdGQ6OmludGVncmFsX2NvbnN0YW50PHVuc2lnbmVkLCAwdT4ge307CiAgICAvLy8gQGJyaWVmIFRoZSBkb21haW4gb2YgbG9nKHgpIGlzIHt4PjB9CiAgICB0ZW1wbGF0ZSA8PgogICAgc3RydWN0IGxvZzI8MHU+IHt9OwogICAgLy8vQH0KCgogICAgLyoqIEBicmllZiBHZW5lcmF0ZXMgdGhlIG1hc2tzIG5lY2Vzc2FyeSBmb3IgZGVpbnRlcmxlYXZpbmcgTW9ydG9uIG51bWJlcnMKICAgICAqIEB0cGFyYW0gc3RlcCAwLWJhc2VkIGluZGV4IG9mIHRoZSBzdGVwOyB0aGlzIGNvcnJlc3BvbmRzIHRvIGEgcnNoaWZ0IG9mCiAgICAgKiAgICAgICAgIGAoQHRwYXJhbSBkaW1lbnNpb25zIC0gMSkgKiAyXkB0cGFyYW0gc3RlcGAuCiAgICAgKiBAdHBhcmFtIGRpbWVuc2lvbnMgaG93IG1hbnkgdmFsdWVzIGFyZSBpbnRlcmxlYXZlZCwgZGVmYXVsdCAyLgogICAgICoKICAgICAqIFRoaXMgZmlsbHMgYSBUIHR5cGUgd2l0aCBhZGphY2VudCBwYXR0ZXJucyBvZiB0aGUgdHlwZSAwLi4uMDEuLi4xIHdoZXJlIHRoZSBudW1iZXIgb2Ygb25lcyBpcyBgMl5AdHBhcmFtIHN0ZXBgCiAgICAgKiBhbmQgdGhlIHRvdGFsIHdpZHRoIGlzIGBAdHBhcmFtIGRpbWVuc2lvbnMgKiAyXkB0cGFyYW0gc3RlcGA7IGkuZS4gZm9yIGBAdHBhcmFtIGRpbWVuc2lvbnMgPSAyYCwgd2UgaGF2ZQogICAgICogICAwLiAwYi4uLjAxMDEwMTAxCiAgICAgKiAgIDEuIDBiLi4uMDAxMTAwMTEKICAgICAqICAgMi4gMGIuLi4wMDAwMTExMQogICAgICovCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgdW5zaWduZWQgc3RlcCwgdW5zaWduZWQgZGltZW5zaW9ucyA9IDJ1PgogICAgdXNpbmcgbWFzayA9IGxzaGlmdF9hZGQ8VCwgbl9vbmVzPFQsIDEgPDwgc3RlcD46OnZhbHVlLCBkaW1lbnNpb25zICogKDEgPDwgc3RlcCksIHNpemVvZihUKSAqIDggLyAoMiA8PCBzdGVwKT47CgoKICAgIC8qKiBAYnJpZWYgUmVjdXJzaXZlbHkgZGVmaW5lcyBhIGZ1bmN0aW9uIHRoYXQgZGVpbnRlcmxlYXZlcyBAdHBhcmFtIGRpbWVuc2lvbnMtZGltZW5zaW9uYWwgTW9ydG9uIG51bWJlcnMuCiAgICAgKiBAbm90ZSBUaGlzIGV4dHJhY3RzIG9ubHkgdGhlIGZpcnN0IGJpdC4gUnNoaWZ0IHRoZSBhcmd1bWVudCBvbmNlIHRvIGdldCB0aGUgbmV4dCBiaXQgYW5kIHNvIG9uLgogICAgICogQHRwYXJhbSBzdGVwIFN0ZXAgb2YgdGhlIGRlaW50ZXJsZWF2ZSBhbGdvcml0aG0uIEVhY2ggb2YgaXQgY29ycmVzcG9uZHMgdG8gYSByc2hpZnQgYW5kIGEgYml0d2lzZSBhbmQgd2l0aCBvbmUgb2YKICAgICAqICAgICAgICAgdGhlIG1hc2tzIGRlZmluZWQgaW4gQHNlZSBtYXNrcy4KICAgICAqIEB0cGFyYW0gZGltZW5zaW9ucyBOdW1iZXIgb2YgY29vcmRpbmF0ZXMgcGFja2VkIGludG8gdGhlIE1vcnRvbiBudW1iZXIuCiAgICAgKi8KICAgIC8vL0B7CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgdW5zaWduZWQgc3RlcCwgdW5zaWduZWQgZGltZW5zaW9ucz4KICAgIHN0cnVjdCBkZWludGVybGVhdmUgewogICAgICAgIHN0YXRpYyBUIHdvcmsoVCBpbnB1dCkgewogICAgICAgICAgICBpbnB1dCA9IGRlaW50ZXJsZWF2ZTxULCBzdGVwIC0gMSwgZGltZW5zaW9ucz46OndvcmsoaW5wdXQpOwogICAgICAgICAgICByZXR1cm4gKGlucHV0IHwgKGlucHV0ID4+ICgoZGltZW5zaW9ucyAtIDEpICogKDEgPDwgKHN0ZXAgLSAxKSkpKSkgJiBtYXNrPFQsIHN0ZXAsIGRpbWVuc2lvbnM+Ojp2YWx1ZTsKICAgICAgICB9CiAgICB9OwogICAgLy8vIEBicmllZiBTcGVjaWFsaXphdGlvbiBmb3Igc3RlcCAwLCB3aGVyZSB0aGVyZSBpcyBqdXN0IGEgYml0d2lzZSBhbmQKICAgIHRlbXBsYXRlIDxjbGFzcyBULCB1bnNpZ25lZCBkaW1lbnNpb25zPgogICAgc3RydWN0IGRlaW50ZXJsZWF2ZTxULCAwdSwgZGltZW5zaW9ucz4gewogICAgICAgIHN0YXRpYyBUIHdvcmsoVCBpbnB1dCkgewogICAgICAgICAgICByZXR1cm4gaW5wdXQgJiBtYXNrPFQsIDB1LCBkaW1lbnNpb25zPjo6dmFsdWU7CiAgICAgICAgfQogICAgfTsKICAgIC8vL0B9CgoKICAgIC8vLyBAYnJpZWYgSGVscGVyIGNvbnN0ZXhwciB3aGljaCByZXR1cm5zIHRoZSBudW1iZXIgb2Ygc3RlcHMgbmVlZGVkIHRvIGZ1bGx5IGludGVybGVhdmUgYSB0eXBlIEB0cGFyYW0gVC4KICAgIHRlbXBsYXRlIDxjbGFzcyBULCB1bnNpZ25lZCBkaW1lbnNpb25zPgogICAgdXNpbmcgbnVtX3N0ZXBzID0gc3RkOjppbnRlZ3JhbF9jb25zdGFudDx1bnNpZ25lZCwgbG9nMjxzaXplb2YoVCkgKiA4IC8gZGltZW5zaW9ucz46OnZhbHVlICsgMT47CgoKICAgIC8vLyBAYnJpZWYgSGVscGVyIGZ1bmN0aW9uIHdoaWNoIGNvbWJpbmVzIEBzZWUgZGVpbnRlcmxlYXZlIGFuZCBAc2VlIG51bV9zdGVwcyBpbnRvIGEgc2luZ2xlIGNhbGwuCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgdW5zaWduZWQgZGltZW5zaW9ucz4KICAgIFQgZGVpbnRlcmxlYXZlX2ZpcnN0KFQgbikgewogICAgICAgIHJldHVybiBkZWludGVybGVhdmU8VCwgbnVtX3N0ZXBzPFQsIGRpbWVuc2lvbnM+Ojp2YWx1ZSAtIDEsIGRpbWVuc2lvbnM+Ojp3b3JrKG4pOwogICAgfQogICAgCiAgICAKICAgIC8vLyBAYnJpZWYgSGVscGVyIGNsYXNzIHdoaWNoIHJlY3Vyc2l2ZWx5IHBhY2tzIGFuIGFycmF5IGJ5IGRlLWludGVybGVhdmluZyBvbmUgY29vcmRpbmF0ZSBhdCBhIHRpbWUKICAgIC8vL0B7CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgdW5zaWduZWQgZGltZW5zaW9ucywgdW5zaWduZWQgaWR4PgogICAgc3RydWN0IGRlaW50ZXJsZWF2ZV9hcnJheSB7CiAgICAgICAgc3RhdGljIHZvaWQgd29yayhUICZuLCBzdGQ6OmFycmF5PFQsIGRpbWVuc2lvbnM+ICZ0dXBsZSkgewogICAgICAgICAgICBzdGQ6OmdldDxpZHg+KHR1cGxlKSA9IGRlaW50ZXJsZWF2ZV9maXJzdDxULCBkaW1lbnNpb25zPihuKTsKICAgICAgICAgICAgZGVpbnRlcmxlYXZlX2FycmF5PFQsIGRpbWVuc2lvbnMsIGlkeCAtIDE+Ojp3b3JrKG4gPj49IDEsIHR1cGxlKTsKICAgICAgICB9CiAgICB9OwogICAgLy8vIEBicmllZiBTcGVjaWFsaXphdGlvbiB0byBzdG9wIHRoZSByZWN1cnNpb24uCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgdW5zaWduZWQgZGltZW5zaW9ucz4KICAgIHN0cnVjdCBkZWludGVybGVhdmVfYXJyYXk8VCwgZGltZW5zaW9ucywgMD4gewogICAgICAgIHN0YXRpYyB2b2lkIHdvcmsoVCAmbiwgc3RkOjphcnJheTxULCBkaW1lbnNpb25zPiAmdHVwbGUpIHsKICAgICAgICAgICAgc3RkOjpnZXQ8MD4odHVwbGUpID0gZGVpbnRlcmxlYXZlX2ZpcnN0PFQsIGRpbWVuc2lvbnM+KG4pOwogICAgICAgIH0KICAgIH07CiAgICAvLy9AfQp9CgoKLy8vIEBicmllZiBFeHRyYWN0IHRoZSBmaXJzdCBjb29yZGluYXRlIGZyb20gYSBNb3J0b24gbnVtYmVyCnRlbXBsYXRlIDxjbGFzcyBULCB1bnNpZ25lZCBkaW1lbnNpb25zID0gMj4KVCBkZWludGVybGVhdmVfb25lKFQgbikgewogICAgcmV0dXJuIGltcGw6OmRlaW50ZXJsZWF2ZV9maXJzdDxULCBkaW1lbnNpb25zPihuKTsKfQoKLy8vIEBicmllZiBFeHRyYWN0IEB0cGFyYW0gZGltZW5zaW9ucyBjb29yZGluYXRlcyBmcm9tIGEgTW9ydG9uIG51bWJlcgp0ZW1wbGF0ZSA8Y2xhc3MgVCwgdW5zaWduZWQgZGltZW5zaW9ucyA9IDI+CnN0ZDo6YXJyYXk8VCwgZGltZW5zaW9ucz4gZGVpbnRlcmxlYXZlX2FsbChUIG4pIHsKICAgIHN0ZDo6YXJyYXk8VCwgZGltZW5zaW9ucz4gcmV0dmFsOwogICAgaW1wbDo6ZGVpbnRlcmxlYXZlX2FycmF5PFQsIGRpbWVuc2lvbnMsIGRpbWVuc2lvbnMgLSAxPjo6d29yayhuLCByZXR2YWwpOwogICAgcmV0dXJuIHJldHZhbDsKfQoKaW50IG1haW4oKSB7CiAgICB1bnNpZ25lZCBuID0gMDsKICAgIHN0ZDo6Y2luID4+IG47CiAgICBzdGQ6OmFycmF5PHVuc2lnbmVkLCAyPiBjb29yZHMgPSBkZWludGVybGVhdmVfYWxsKG4pOwogICAgc3RkOjpjb3V0IDw8IGNvb3Jkc1swXSA8PCAiXHQiIDw8IGNvb3Jkc1sxXSA8PCBzdGQ6OmVuZGw7CiAgICByZXR1cm4gMDsKfQo=