#include // {{{ // https://codeforces.com/blog/entry/96344 #pragma GCC optimize("O2,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") using namespace std; template constexpr T MIN = std::numeric_limits::min(); template constexpr T MAX = std::numeric_limits::max(); template [[nodiscard]] static T sc(auto&& x) { return static_cast(x); } template [[nodiscard]] static T sz(auto&& x) { return static_cast(x.size()); } #define prln(...) std::println(__VA_ARGS__) #define pr(...) std::print(__VA_ARGS__) #ifdef LOCAL #define dbgln(...) std::println(__VA_ARGS__) #define dbg(...) std::print(__VA_ARGS__) #endif using ll = long long; using ld = long double; template using v = std::vector; template using r = std::array; template using p = std::pair; #define ff first #define ss second #define eb emplace_back #define pb push_back #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() // }}} template struct segment_tree { public: explicit segment_tree(std::vector const& ts) : n(ts.size()) { tree.resize(4 * n); build(1, 0, n - 1, ts); } [[nodiscard]] T const query(int const l, int const r) const { if (!(0 <= l && l <= r && r < static_cast(n))) { throw std::out_of_range( "cannot query segment tree of size " + std::to_string(n) + " at range [" + std::to_string(l) + ", " + std::to_string(r) + "]"); } return query(1, 0, n - 1, l, r); } void update(int i, T const& t) { if (!(0 <= i && i < static_cast(n))) { throw std::out_of_range("cannot update segment tree of size " + std::to_string(n) + " at index " + std::to_string(i)); } update(1, 0, n - 1, i, t); } private: inline T const sentinel() const noexcept { return MAX; } inline T const merge(T const& x, T const& y) const noexcept { return min(x, y); } void build(size_t const node, size_t const l, size_t const r, std::vector const& ts) noexcept { if (l == r) { tree[node] = ts[l]; } else { int m = l + (r - l) / 2; build(2 * node, l, m, ts); build(2 * node + 1, m + 1, r, ts); tree[node] = merge(tree[2 * node], tree[2 * node + 1]); } } [[nodiscard]] T query(size_t const node, size_t const lower, size_t const upper, size_t const l, size_t const r) const noexcept { if (upper < l || r < lower) { return sentinel(); } if (l <= lower && upper <= r) { return tree[node]; } size_t m = lower + (upper - lower) / 2; return merge(query(2 * node, lower, m, l, r), query(2 * node + 1, m + 1, upper, l, r)); } void update(size_t const node, size_t const l, size_t const r, size_t const i, T const& t) noexcept { if (l == r) { tree[node] = t; } else { size_t m = l + (r - l) / 2; if (i <= m) { update(2 * node, l, m, i, t); } else { update(2 * node + 1, m + 1, r, i, t); } tree[node] = merge(tree[2 * node], tree[2 * node + 1]); } } size_t n; std::vector tree; }; void solve() { int n, q; cin >> n >> q; v a(n); for (auto& e : a) { cin >> e; } segment_tree st(a); while (q--) { char cmd; cin >> cmd; if (cmd == '1') { int i; ll u; cin >> i >> u; --i; st.update(i, u); a[i] = u; } else { int l, r; cin >> l >> r; --l; --r; cout << st.query(l, r) << endl; } } } int main() { // {{{ cin.tie(nullptr)->sync_with_stdio(false); int t = 1; // cin >> t; while (t--) { solve(); } return 0; } // }}}