// BEGIN: ../contest596/A/main.cpp #line 1 "..::contest596::A::main.cpp" // BEGIN: pch.hpp #line 3 "pch.hpp" #if defined(__GNUC__) && !defined(__clang__) #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #endif #define dump(...) #define CPP_DUMP_SET_OPTION(...) #define CPP_DUMP_DEFINE_EXPORT_OBJECT(...) #define CPP_DUMP_DEFINE_EXPORT_ENUM(...) #define CPP_DUMP_DEFINE_DANGEROUS_EXPORT_OBJECT(...) // BEGIN: template.hpp #line 3 "template.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // BEGIN: utilities/fast_io.hpp #line 3 "utilities::fast_io.hpp" #include #include #include #include #include #include #include #include #include #include #include #include namespace m1une { namespace utilities { namespace internal { // Detect std::begin(x), std::end(x). template struct is_range : std::false_type {}; template struct is_range())), decltype(std::end(std::declval())) >> : std::true_type {}; template inline constexpr bool is_range_v = is_range::value; template using range_reference_t = decltype(*std::begin(std::declval())); template using range_value_t = std::remove_cv_t>>; template struct range_stored_value { using type = range_value_t; }; template struct range_stored_value>::value_type>> { using type = typename std::remove_cv_t>::value_type; }; template using range_stored_value_t = typename range_stored_value::type; // Treat strings and C strings as scalar output objects, not as ranges. template struct is_char_array : std::false_type {}; template struct is_char_array : std::bool_constant, char>> {}; template struct is_string_like : std::bool_constant< std::is_same_v, std::string> || std::is_same_v, const char*> || std::is_same_v, char*> || is_char_array>::value > {}; template inline constexpr bool is_string_like_v = is_string_like::value; // ModInt-like type: x.val() is printable, and x can be assigned from long long. template struct has_val_method : std::false_type {}; template struct has_val_method().val())>> : std::true_type {}; template inline constexpr bool has_val_method_v = has_val_method::value; template struct has_static_mod_raw : std::false_type {}; template struct has_static_mod_raw< T, std::void_t()))>> : std::true_type {}; template inline constexpr bool has_static_mod_raw_v = has_static_mod_raw::value; // libstdc++ before GCC 16 does not classify __int128 as an integral type in // strict ISO modes such as -std=c++23. Keep the fast-I/O interface independent // of that implementation detail. template inline constexpr bool is_integral_v = std::is_integral_v || std::is_same_v, __int128_t> || std::is_same_v, __uint128_t>; template inline constexpr bool is_signed_v = std::is_signed_v || std::is_same_v, __int128_t>; template struct make_unsigned { using type = std::make_unsigned_t; }; template <> struct make_unsigned<__int128_t> { using type = __uint128_t; }; template <> struct make_unsigned<__uint128_t> { using type = __uint128_t; }; template using make_unsigned_t = typename make_unsigned>::type; } // namespace internal struct FastInput { static constexpr int buffer_size = 1 << 20; private: std::FILE* _stream; char _buffer[buffer_size]; int _position; int _length; bool _terminal; bool refill() { _position = 0; if (_terminal) { if (std::fgets(_buffer, buffer_size, _stream) == nullptr) { _length = 0; return false; } _length = int(std::strlen(_buffer)); } else { _length = int(std::fread(_buffer, 1, buffer_size, _stream)); } return _length != 0; } template bool read_integer_from_terminal(T& value) { if (!skip_spaces()) return false; int c = read_char_raw(); bool negative = false; if (c == '-') { negative = true; c = read_char_raw(); } if constexpr (internal::is_signed_v) { T result = 0; while ('0' <= c && c <= '9') { result = negative ? result * 10 - (c - '0') : result * 10 + (c - '0'); c = read_char_raw(); } value = result; } else { T result = 0; while ('0' <= c && c <= '9') { result = result * 10 + T(c - '0'); c = read_char_raw(); } value = negative ? T(0) - result : result; } return true; } bool prepare_number() { if (_length - _position >= 64) return true; const int remaining = _length - _position; if (remaining > 0) std::memmove(_buffer, _buffer + _position, remaining); const int added = int(std::fread(_buffer + remaining, 1, buffer_size - remaining, _stream)); _position = 0; _length = remaining + added; if (_length < buffer_size) _buffer[_length] = '\0'; return _length != 0; } public: explicit FastInput(std::FILE* stream = stdin) : _stream(stream), _position(0), _length(0), _terminal(::isatty(::fileno(stream)) != 0) {} FastInput(const FastInput&) = delete; FastInput& operator=(const FastInput&) = delete; int read_char_raw() { if (_position == _length && !refill()) return EOF; return _buffer[_position++]; } bool skip_spaces() { int c = read_char_raw(); while (c != EOF && c <= ' ') c = read_char_raw(); if (c == EOF) return false; --_position; return true; } bool read(char& value) { if (!skip_spaces()) return false; value = char(read_char_raw()); return true; } bool read(std::string& value) { if (!skip_spaces()) return false; value.clear(); int c = read_char_raw(); while (c != EOF && c > ' ') { value.push_back(char(c)); c = read_char_raw(); } return true; } bool read(bool& value) { int x; if (!read(x)) return false; value = x != 0; return true; } template std::enable_if_t< internal::is_integral_v && !std::is_same_v, bool> && !std::is_same_v, char>, bool > read(T& value) { if (_terminal) return read_integer_from_terminal(value); if (!prepare_number()) return false; int c = static_cast(_buffer[_position++]); while (c <= ' ') c = static_cast(_buffer[_position++]); bool negative = false; if (c == '-') { negative = true; c = static_cast(_buffer[_position++]); } if constexpr (internal::is_signed_v) { T result = 0; while ('0' <= c && c <= '9') { const int first = c - '0'; const int second = static_cast(_buffer[_position]) - '0'; if (0 <= second && second <= 9) { result = negative ? result * 100 - (first * 10 + second) : result * 100 + (first * 10 + second); ++_position; } else { result = negative ? result * 10 - first : result * 10 + first; } c = static_cast(_buffer[_position++]); } value = result; } else { T result = 0; while ('0' <= c && c <= '9') { const unsigned first = unsigned(c - '0'); const int second = static_cast(_buffer[_position]) - '0'; if (0 <= second && second <= 9) { result = result * 100 + T(first * 10 + unsigned(second)); ++_position; } else { result = result * 10 + T(first); } c = static_cast(_buffer[_position++]); } value = negative ? T(0) - result : result; } if (_position > _length) _position = _length; return true; } template std::enable_if_t, bool> read(T& value) { if (!skip_spaces()) return false; int c = read_char_raw(); bool negative = false; if (c == '-' || c == '+') { negative = c == '-'; c = read_char_raw(); } long double result = 0; while ('0' <= c && c <= '9') { result = result * 10 + (c - '0'); c = read_char_raw(); } if (c == '.') { long double place = 0.1L; c = read_char_raw(); while ('0' <= c && c <= '9') { result += (c - '0') * place; place *= 0.1L; c = read_char_raw(); } } if (c == 'e' || c == 'E') { c = read_char_raw(); bool exponent_negative = false; if (c == '-' || c == '+') { exponent_negative = c == '-'; c = read_char_raw(); } int exponent = 0; while ('0' <= c && c <= '9') { exponent = exponent * 10 + (c - '0'); c = read_char_raw(); } long double scale = 1; long double power = 10; while (exponent > 0) { if (exponent & 1) scale *= power; power *= power; exponent >>= 1; } result = exponent_negative ? result / scale : result * scale; } value = static_cast(negative ? -result : result); return true; } template std::enable_if_t< internal::has_val_method_v && !internal::is_integral_v && !internal::is_range_v, bool > read(T& value) { long long x; if (!read(x)) return false; if constexpr (internal::has_static_mod_raw_v) { if (x >= 0 && uint64_t(x) < uint64_t(T::mod())) { value = T::raw(uint32_t(x)); } else { value = T(x); } } else { value = T(x); } return true; } template bool read(std::pair& value) { if (!read(value.first)) return false; return read(value.second); } template std::enable_if_t< internal::is_range_v && !internal::is_string_like_v, bool > read(Range& range) { using StoredValue = internal::range_stored_value_t; constexpr bool nested = internal::is_range_v && !internal::is_string_like_v; for (auto&& value : range) { if constexpr (std::is_same_v && !nested) { bool x; if (!read(x)) return false; value = x; } else { if (!read(value)) return false; } } return true; } template bool read(First& first, Second& second, Rest&... rest) { if (!read(first)) return false; return read(second, rest...); } template FastInput& operator>>(T& value) { if (!read(value)) std::abort(); return *this; } }; struct FastOutput { static constexpr int buffer_size = 1 << 20; private: inline static const auto digit_quads = [] { std::array result{}; for (int i = 0; i < 10000; i++) { int value = i; for (int j = 3; j >= 0; j--) { result[4 * i + j] = char('0' + value % 10); value /= 10; } } return result; }(); std::FILE* _stream; char _buffer[buffer_size]; int _position; int _precision; std::chars_format _float_format; char _range_separator; public: explicit FastOutput(std::FILE* stream = stdout) : _stream(stream), _position(0), _precision(6), _float_format(std::chars_format::general), _range_separator(' ') {} FastOutput(const FastOutput&) = delete; FastOutput& operator=(const FastOutput&) = delete; ~FastOutput() { flush(); } void flush() { if (_position == 0) return; std::fwrite(_buffer, 1, _position, _stream); _position = 0; } void write_char(char c) { if (_position == buffer_size) flush(); _buffer[_position++] = c; } void write(const char* s) { while (*s != '\0') write_char(*s++); } void write(const std::string& s) { for (char c : s) write_char(c); } void write(char c) { write_char(c); } void write(bool value) { write_char(value ? '1' : '0'); } template std::enable_if_t> write(T value) { char digits[128]; auto [end, error] = std::to_chars( digits, digits + sizeof(digits), value, _float_format, _precision ); if (error != std::errc()) std::abort(); for (const char* pointer = digits; pointer != end; pointer++) { write_char(*pointer); } } template std::enable_if_t< internal::is_integral_v && !std::is_same_v, bool> && !std::is_same_v, char> > write(T value) { using Raw = std::remove_cv_t; using Unsigned = internal::make_unsigned_t; Unsigned magnitude; if constexpr (internal::is_signed_v) { if (value < 0) { write_char('-'); magnitude = Unsigned(0) - Unsigned(value); } else { magnitude = Unsigned(value); } } else { magnitude = value; } if (magnitude == 0) { write_char('0'); return; } unsigned chunks[16]; int count = 0; while (magnitude >= 10000) { const Unsigned quotient = magnitude / 10000; chunks[count++] = unsigned(magnitude - quotient * 10000); magnitude = quotient; } if (_position > buffer_size - 64) flush(); const unsigned leading = unsigned(magnitude); const char* first = digit_quads.data() + 4 * leading; int skip = leading < 10 ? 3 : leading < 100 ? 2 : leading < 1000 ? 1 : 0; for (; skip < 4; skip++) _buffer[_position++] = first[skip]; while (count--) { const char* digits = digit_quads.data() + 4 * chunks[count]; std::memcpy(_buffer + _position, digits, 4); _position += 4; } } template std::enable_if_t< internal::has_val_method_v && !internal::is_integral_v && !internal::is_range_v > write(const T& value) { write(value.val()); } template void write(const std::pair& value) { write(value.first); write_char(' '); write(value.second); } template std::enable_if_t< internal::is_range_v && !internal::is_string_like_v > write(const Range& range) { using StoredValue = internal::range_stored_value_t; constexpr bool nested = internal::is_range_v && !internal::is_string_like_v; bool first = true; for (const auto& value : range) { if (!first) write_char(nested ? '\n' : _range_separator); first = false; if constexpr (std::is_same_v && !nested) { write(static_cast(value)); } else { write(value); } } } template void print(const First& first, const Rest&... rest) { write(first); ((write_char(' '), write(rest)), ...); } void println() { write_char('\n'); } void set_precision(int precision) { _precision = precision; } void set_fixed(int precision = 6) { _float_format = std::chars_format::fixed; _precision = precision; } void set_general(int precision = 6) { _float_format = std::chars_format::general; _precision = precision; } void set_range_separator(char separator) { _range_separator = separator; } template void println(const Args&... args) { print(args...); write_char('\n'); } template FastOutput& operator<<(const T& value) { write(value); return *this; } }; } // namespace utilities } // namespace m1une // END: utilities/fast_io.hpp #line 103 "template.hpp" using namespace std; namespace m1une { namespace template_io { inline utilities::FastInput& input() { static utilities::FastInput instance; return instance; } inline utilities::FastOutput& output() { static utilities::FastOutput instance; return instance; } } // namespace template_io } // namespace m1une using ll = long long; using u32 = unsigned int; using u64 = unsigned long long; using i128 = __int128; using u128 = unsigned __int128; #ifdef __SIZEOF_FLOAT128__ using f128 = __float128; #endif template constexpr T infty = 0; template <> constexpr int infty = 1'000'000'000; template <> constexpr ll infty = ll(infty) * infty * 2; template <> constexpr u32 infty = infty; template <> constexpr u64 infty = infty; template <> constexpr i128 infty = i128(infty) * infty; template <> constexpr double infty = infty; template <> constexpr long double infty = infty; using pi = pair; using pl = pair; using vi = vector; using vl = vector; template using vc = vector; template using vvc = vector>; using vvi = vvc; using vvl = vvc; template using vvvc = vector>; template using vvvvc = vector>; template using vvvvvc = vector>; template using pqg = std::priority_queue, greater>; template using umap = unordered_map; // template // using tree = __gnu_pbds::tree, // __gnu_pbds::rb_tree_tag, // __gnu_pbds::tree_order_statistics_node_update>; #define vv(type, name, h, ...) vector> name(h, vector(__VA_ARGS__)) #define vvv(type, name, h, w, ...) \ vector>> name(h, vector>(w, vector(__VA_ARGS__))) #define vvvv(type, name, a, b, c, ...) \ vector>>> name( \ a, vector>>(b, vector>(c, vector(__VA_ARGS__)))) #define overload4(a, b, c, d, e, ...) e #define overload3(a, b, c, d, ...) d // FOR(a) := for (ll _ = 0; _ < (ll)a; ++_) // FOR(i, a) := for (ll i = 0; i < (ll)a; ++i) // FOR(i, a, b) := for (ll i = a; i < (ll)b; ++i) // FOR(i, a, b, c) := for (ll i = a; i < (ll)b; i += (c)) // FOR_R(a) := for (ll i = (a) - 1; i >= 0; --i) // FOR_R(i, a) := for (ll i = (a) - 1; i >= 0; --i) // FOR_R(i, a, b) := for (ll i = (b) - 1; i >= (ll)a; --i) #define FOR1(a) for (ll _ = 0; _ < (ll)a; ++_) #define FOR2(i, a) for (ll i = 0; i < (ll)a; ++i) #define FOR3(i, a, b) for (ll i = a; i < (ll)b; ++i) #define FOR4(i, a, b, c) for (ll i = a; i < (ll)b; i += (c)) #define FOR1_R(a) for (ll i = (a) - 1; i >= 0; --i) #define FOR2_R(i, a) for (ll i = (a) - 1; i >= 0; --i) #define FOR3_R(i, a, b) for (ll i = (b) - 1; i >= (ll)a; --i) #define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__) #define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__) #define FORI1(a) for (int _ = 0; _ < (int)a; ++_) #define FORI2(i, a) for (int i = 0; i < (int)a; ++i) #define FORI3(i, a, b) for (int i = a; i < (int)b; ++i) #define FORI4(i, a, b, c) for (int i = a; i < (int)b; i += (c)) #define FORI1_R(a) for (int i = (a) - 1; i >= 0; --i) #define FORI2_R(i, a) for (int i = (a) - 1; i >= 0; --i) #define FORI3_R(i, a, b) for (int i = (b) - 1; i >= (int)a; --i) #define FORI(...) overload4(__VA_ARGS__, FORI4, FORI3, FORI2, FORI1)(__VA_ARGS__) #define FORI_R(...) overload3(__VA_ARGS__, FORI3_R, FORI2_R, FORI1_R)(__VA_ARGS__) #define FOR_subset(t, s) for (int t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s))) #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() int popcnt(int x) { return __builtin_popcount(x); } int popcnt(u32 x) { return __builtin_popcount(x); } int popcnt(ll x) { return __builtin_popcountll(x); } int popcnt(u64 x) { return __builtin_popcountll(x); } int popcnt_mod_2(int x) { return __builtin_parity(x); } int popcnt_mod_2(u32 x) { return __builtin_parity(x); } int popcnt_mod_2(ll x) { return __builtin_parityll(x); } int popcnt_mod_2(u64 x) { return __builtin_parityll(x); } // (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2) int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); } int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); } int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); } int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); } // (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2) int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); } int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); } int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); } int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); } template T floor(T a, T b) { return a / b - (a % b && (a ^ b) < 0); } template T ceil(T x, T y) { return floor(x + y - 1, y); } template T bmod(T x, T y) { return x - y * floor(x, y); } template pair divmod(T x, T y) { T q = floor(x, y); return {q, x - q * y}; } template T POW(U x_, int n) { T x = x_; T ret = 1; while (n > 0) { if (n & 1) ret *= x; x *= x; n >>= 1; } return ret; } template T SUM(const vector& A) { T sm = 0; for (auto&& a : A) sm += a; return sm; } #define LB(c, x) distance((c).begin(), lower_bound(all(c), (x))) #define UB(c, x) distance((c).begin(), upper_bound(all(c), (x))) #define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit() template inline bool chmax(T& a, const S& b) { return (a < b ? a = b, 1 : 0); } template inline bool chmin(T& a, const S& b) { return (a > b ? a = b, 1 : 0); } // ? は -1 vc s_to_vi(const string& S, char first_char) { vc A(S.size()); FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); } return A; } template vector cumsum(vector& A, int off = 1) { int N = A.size(); vector B(N + 1); FOR(i, N) { B[i + 1] = B[i] + A[i]; } if (off == 0) B.erase(B.begin()); return B; } template vector argsort(const vector& A) { vector ids(A.size()); iota(all(ids), 0); sort(all(ids), [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); }); return ids; } // A[I[0]], A[I[1]], ... template vc rearrange(const vc& A, const vc& I) { vc B(I.size()); FOR(i, I.size()) B[i] = A[I[i]]; return B; } template constexpr auto min(T... a) { return min(initializer_list>{a...}); } template constexpr auto max(T... a) { return max(initializer_list>{a...}); } template bool scan(Ts&... values) { return m1une::template_io::input().read(values...); } template void print(const Ts&... values) { m1une::template_io::output().println(values...); } void YESNO(bool b) { m1une::template_io::output().println(b ? "YES" : "NO"); } void YesNo(bool b) { m1une::template_io::output().println(b ? "Yes" : "No"); } void YES() { m1une::template_io::output().println("YES"); } void NO() { m1une::template_io::output().println("NO"); } void Yes() { m1une::template_io::output().println("Yes"); } void No() { m1une::template_io::output().println("No"); } // END: template.hpp #line 29 "pch.hpp" // END: pch.hpp #line 2 "..::contest596::A::main.cpp" auto& fastin = m1une::template_io::input(); auto& fastout = m1une::template_io::output(); // BEGIN: ds/dynamic_array/dynamic_array.hpp #line 3 "ds::dynamic_array::dynamic_array.hpp" #include #include #include #include #include #include namespace m1une { namespace ds { template struct DynamicArray { private: struct Node { T val; int priority; int count; int l, r; bool rev; Node() : val(T()), priority(0), count(0), l(0), r(0), rev(false) {} Node(T value, int node_priority) : val(std::move(value)), priority(node_priority), count(1), l(0), r(0), rev(false) {} }; std::vector pool; int root; std::uint32_t rng_state; int new_node(T val) { pool.push_back(Node(std::move(val), next_priority())); return pool.size() - 1; } int next_priority() { rng_state ^= rng_state << 13; rng_state ^= rng_state >> 17; rng_state ^= rng_state << 5; return int(rng_state); } void update(int t) { if (t) { pool[t].count = 1 + pool[pool[t].l].count + pool[pool[t].r].count; } } void apply_reverse(int t) { if (t) { pool[t].rev = !pool[t].rev; } } void push(int t) { if (!t || !pool[t].rev) return; std::swap(pool[t].l, pool[t].r); apply_reverse(pool[t].l); apply_reverse(pool[t].r); pool[t].rev = false; } void split(int t, int pos, int& l, int& r) { if (!t) { l = r = 0; return; } if (pos == 0) { l = 0; r = t; return; } if (pos == pool[t].count) { l = t; r = 0; return; } push(t); int left_count = pool[pool[t].l].count; if (pos == left_count) { l = pool[t].l; pool[t].l = 0; update(t); r = t; return; } if (pos == left_count + 1) { r = pool[t].r; pool[t].r = 0; update(t); l = t; return; } if (pos <= left_count) { split(pool[t].l, pos, l, pool[t].l); r = t; } else { split(pool[t].r, pos - left_count - 1, pool[t].r, r); l = t; } update(t); } int merge(int l, int r) { if (!l || !r) return l ? l : r; if (pool[l].priority > pool[r].priority) { push(l); if (pool[l].r) { pool[l].r = merge(pool[l].r, r); } else { pool[l].r = r; } update(l); return l; } else { push(r); if (pool[r].l) { pool[r].l = merge(l, pool[r].l); } else { pool[r].l = l; } update(r); return r; } } int insert_node(int t, int pos, int node) { if (!t) return node; if (pool[node].priority > pool[t].priority) { split(t, pos, pool[node].l, pool[node].r); update(node); return node; } push(t); int left_count = pool[pool[t].l].count; if (pos <= left_count) { pool[t].l = insert_node(pool[t].l, pos, node); } else { pool[t].r = insert_node(pool[t].r, pos - left_count - 1, node); } update(t); return t; } int erase_node(int t, int pos) { push(t); int left_count = pool[pool[t].l].count; if (pos < left_count) { pool[t].l = erase_node(pool[t].l, pos); update(t); return t; } if (pos == left_count) { return merge(pool[t].l, pool[t].r); } pool[t].r = erase_node(pool[t].r, pos - left_count - 1); update(t); return t; } int find_node(int t, int pos) { while (t) { push(t); int left_count = pool[pool[t].l].count; if (pos < left_count) { t = pool[t].l; } else if (pos == left_count) { return t; } else { pos -= left_count + 1; t = pool[t].r; } } return 0; } int find_node(int t, int pos, bool reversed) const { while (t) { bool cur_reversed = reversed ^ pool[t].rev; int left = cur_reversed ? pool[t].r : pool[t].l; int right = cur_reversed ? pool[t].l : pool[t].r; int left_count = pool[left].count; if (pos < left_count) { t = left; reversed = cur_reversed; } else if (pos == left_count) { return t; } else { pos -= left_count + 1; t = right; reversed = cur_reversed; } } return 0; } void dump_dfs(int t, std::vector& res, bool reversed = false) const { if (!t) return; bool cur_reversed = reversed ^ pool[t].rev; int left = cur_reversed ? pool[t].r : pool[t].l; int right = cur_reversed ? pool[t].l : pool[t].r; dump_dfs(left, res, cur_reversed); res.push_back(pool[t].val); dump_dfs(right, res, cur_reversed); } void dump_range_dfs(int t, int ql, int qr, int offset, std::vector& res, bool reversed = false) const { if (!t || qr <= offset || offset + pool[t].count <= ql) return; bool cur_reversed = reversed ^ pool[t].rev; int left = cur_reversed ? pool[t].r : pool[t].l; int right = cur_reversed ? pool[t].l : pool[t].r; int left_count = pool[left].count; int node_pos = offset + left_count; dump_range_dfs(left, ql, qr, offset, res, cur_reversed); if (ql <= node_pos && node_pos < qr) { res.push_back(pool[t].val); } dump_range_dfs(right, ql, qr, node_pos + 1, res, cur_reversed); } int clone_subtree_from(const DynamicArray& other, int t) { if (!t) return 0; int res = static_cast(pool.size()); pool.push_back(other.pool[t]); pool[res].l = clone_subtree_from(other, other.pool[t].l); pool[res].r = clone_subtree_from(other, other.pool[t].r); return res; } void update_dfs(int t) { if (!t) return; update_dfs(pool[t].l); update_dfs(pool[t].r); update(t); } int build_cartesian(int first, int last) { if (first == last) return 0; std::vector stack; stack.reserve(last - first); for (int i = first; i < last; i++) { int left_child = 0; while (!stack.empty() && pool[stack.back()].priority < pool[i].priority) { left_child = stack.back(); stack.pop_back(); } pool[i].l = left_child; if (!stack.empty()) { pool[stack.back()].r = i; } stack.push_back(i); } int res = stack.front(); update_dfs(res); return res; } int build_from_vector(const std::vector& v) { int first = int(pool.size()); pool.reserve(pool.size() + v.size()); for (const T& x : v) { new_node(x); } return build_cartesian(first, int(pool.size())); } int build_from_vector(std::vector&& v) { int first = int(pool.size()); pool.reserve(pool.size() + v.size()); for (T& x : v) { new_node(std::move(x)); } return build_cartesian(first, int(pool.size())); } void reset_to_empty() { pool.clear(); pool.push_back(Node()); root = 0; } public: DynamicArray() : root(0), rng_state(std::uint32_t(std::chrono::steady_clock::now().time_since_epoch().count())) { pool.push_back(Node()); if (rng_state == 0) rng_state = 1; } DynamicArray(const DynamicArray& other) : pool(other.pool), root(other.root), rng_state(other.rng_state) {} DynamicArray(DynamicArray&& other) noexcept : pool(std::move(other.pool)), root(other.root), rng_state(other.rng_state) { other.reset_to_empty(); } DynamicArray& operator=(const DynamicArray& other) { if (this != &other) { pool = other.pool; root = other.root; rng_state = other.rng_state; } return *this; } DynamicArray& operator=(DynamicArray&& other) noexcept { if (this != &other) { pool = std::move(other.pool); root = other.root; rng_state = other.rng_state; other.reset_to_empty(); } return *this; } explicit DynamicArray(int n) : DynamicArray(n, T()) {} DynamicArray(int n, const T& value) : DynamicArray() { assert(0 <= n); pool.reserve(n + 1); int first = int(pool.size()); for (int i = 0; i < n; i++) { new_node(value); } root = build_cartesian(first, int(pool.size())); } explicit DynamicArray(const std::vector& v) : DynamicArray() { pool.reserve(v.size() + 1); root = build_from_vector(v); } explicit DynamicArray(std::vector&& v) : DynamicArray() { pool.reserve(v.size() + 1); root = build_from_vector(std::move(v)); } DynamicArray(std::initializer_list init) : DynamicArray() { pool.reserve(init.size() + 1); for (const T& x : init) push_back(x); } int size() const { return pool[root].count; } bool empty() const { return size() == 0; } void clear() { reset_to_empty(); } void insert(int pos, T val) { assert(0 <= pos && pos <= size()); root = insert_node(root, pos, new_node(std::move(val))); } void insert(int pos, const std::vector& v) { assert(0 <= pos && pos <= size()); pool.reserve(pool.size() + v.size()); int mid = build_from_vector(v); int l, r; split(root, pos, l, r); root = merge(merge(l, mid), r); } void insert(int pos, std::vector&& v) { assert(0 <= pos && pos <= size()); pool.reserve(pool.size() + v.size()); int mid = build_from_vector(std::move(v)); int l, r; split(root, pos, l, r); root = merge(merge(l, mid), r); } void insert(int pos, std::initializer_list init) { insert(pos, std::vector(init)); } void insert(int pos, const DynamicArray& other) { assert(0 <= pos && pos <= size()); if (other.empty()) return; pool.reserve(pool.size() + other.size()); int mid = clone_subtree_from(other, other.root); int l, r; split(root, pos, l, r); root = merge(merge(l, mid), r); } void push_back(T val) { insert(size(), std::move(val)); } void push_front(T val) { insert(0, std::move(val)); } void append(const std::vector& v) { insert(size(), v); } void append(std::vector&& v) { insert(size(), std::move(v)); } void append(const DynamicArray& other) { insert(size(), other); } void erase(int pos) { assert(0 <= pos && pos < size()); root = erase_node(root, pos); } void erase(int l, int r) { assert(0 <= l && l <= r && r <= size()); if (l == r) return; int a, b, c; split(root, l, a, b); split(b, r - l, b, c); root = merge(a, c); } void pop_back() { assert(!empty()); erase(size() - 1); } void pop_front() { assert(!empty()); erase(0); } T& at(int pos) { assert(0 <= pos && pos < size()); return pool[find_node(root, pos)].val; } const T& at(int pos) const { assert(0 <= pos && pos < size()); return pool[find_node(root, pos, false)].val; } T& operator[](int pos) { return at(pos); } const T& operator[](int pos) const { return at(pos); } T& front() { assert(!empty()); return at(0); } const T& front() const { assert(!empty()); return at(0); } T& back() { assert(!empty()); return at(size() - 1); } const T& back() const { assert(!empty()); return at(size() - 1); } void reverse(int l, int r) { assert(0 <= l && l <= r && r <= size()); if (l == r) return; int a, b, c; split(root, l, a, b); split(b, r - l, b, c); apply_reverse(b); root = merge(merge(a, b), c); } void reverse() { apply_reverse(root); } void rotate(int l, int m, int r) { assert(0 <= l && l <= m && m <= r && r <= size()); if (l == m || m == r) return; int a, b, c, d; split(root, l, a, b); split(b, m - l, b, c); split(c, r - m, c, d); root = merge(merge(a, c), merge(b, d)); } T get(int pos) const { return at(pos); } void set(int pos, T val) { at(pos) = std::move(val); } std::vector to_vector() const { std::vector res; res.reserve(size()); dump_dfs(root, res); return res; } std::vector to_vector(int l, int r) const { assert(0 <= l && l <= r && r <= size()); std::vector res; res.reserve(r - l); dump_range_dfs(root, l, r, 0, res); return res; } DynamicArray split_off(int pos) { assert(0 <= pos && pos <= size()); int l, r; split(root, pos, l, r); root = l; DynamicArray res; res.pool.reserve(pool[r].count + 1); res.root = res.clone_subtree_from(*this, r); return res; } }; } // namespace ds } // namespace m1une // END: ds/dynamic_array/dynamic_array.hpp #line 7 "..::contest596::A::main.cpp" void solve() { ll N; scan(N); m1une::ds::DynamicArray arr(1, 0); ll inv = 0; FOR(i, 1, N) { print('?', 1, i + 1); fastout.flush(); ll X; scan(X); ll p = X - inv; arr.insert(p, i); inv = X; } arr.reverse(); vl ans(N); FOR(i, N) { ans[arr[i]] = i + 1; } print(ans); fastout.flush(); } int main() { CPP_DUMP_SET_OPTION(max_line_width, 80); CPP_DUMP_SET_OPTION(log_label_func, cpp_dump::log_label::filename()); CPP_DUMP_SET_OPTION(enable_asterisk, true); int T = 1; // cin >> T; while (T--) solve(); return 0; } // END: ../contest596/A/main.cpp