Problem:
Range Minimum Query (RMQ)

Write a program which manipulates a sequence A = {a0, a1, . . . , an-1} with the following operations:

find(s, t): report the minimum element in as, as+1, . . . ,at.

update(i, x): change ai to x.

Note that the initial values of ai (i = 0, 1, . . . , n−1) are 231-1.

Input

n q
com0 x0 y0
com1 x1 y1
...
comq−1 xq−1 yq−1

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, q queries are given where com represents the type of queries. '0' denotes update(xi, yi) and '1' denotes find(xi, yi).

Output

For each find operation, print the minimum element.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

If comi is 0, then 0 ≤ xi < n, 0 ≤ yi < 231-1.

If comi is 1, then 0 ≤ xi < n, 0 ≤ yi < n.

Sample Input 1

3 5
0 0 1
0 1 2
0 2 3
1 0 2
1 1 2

Sample Output 1

1
2

Sample Input 2

1 3
1 0 0
0 0 5
1 0 0

Sample Output 2

2147483647
5

Solution in Rust (judge verdict: Accepted)

use std::cmp;
use std::collections::HashMap;
use std::io::*;
use std::str::FromStr;
use std::string::String;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();

    token.parse().ok().expect("failed to parse token")
}

#[derive(Eq, PartialEq, Clone, Debug)]
pub struct Rev<T>(pub T);

impl<T: PartialOrd> PartialOrd for Rev<T> {
    fn partial_cmp(&self, other: &Rev<T>) -> Option<std::cmp::Ordering> {
        other.0.partial_cmp(&self.0)
    }
}

impl<T: Ord> Ord for Rev<T> {
    fn cmp(&self, other: &Rev<T>) -> std::cmp::Ordering {
        other.0.cmp(&self.0)
    }
}

struct SegmentTree<Monoid, Operator> {
    size: usize,
    node: Vec<Monoid>,
    f: Operator,
    e: Monoid,
}

impl<Monoid, Operator> SegmentTree<Monoid, Operator>
where
    Operator: Fn(Monoid, Monoid) -> Monoid,
    Monoid: Copy,
{
    pub fn new(n: usize, f: Operator, e: Monoid) -> Self {
        let mut size = 1;
        while size < n {
            size *= 2
        }

        SegmentTree {
            size: size,
            node: vec![e; size * 2],
            f: f,
            e: e,
        }
    }

    pub fn update(&mut self, idx: usize, x: Monoid) {
        let mut k = idx + self.size - 1;
        self.node[k] = x;
        while k > 0 {
            k = (k - 1) / 2;
            self.node[k] = (self.f)(self.node[2 * k + 1], self.node[2 * k + 2]);
        }
    }

    pub fn query(&self, a: usize, b: usize) -> Monoid {
        return self._query(a, b, 0, 0, self.size);
    }

    fn _query(&self, a: usize, b: usize, idx: usize, l: usize, r: usize) -> Monoid {
        if r <= a || b <= l {
            return self.e;
        }

        if a <= l && r <= b {
            return self.node[idx];
        }

        let xl: Monoid = self._query(a, b, 2 * idx + 1, l, (l + r) / 2);
        let xr: Monoid = self._query(a, b, 2 * idx + 2, (r + l) / 2, r);

        return (self.f)(xl, xr);
    }
}

fn main() {
    let (n, q): (usize, usize) = (read(), read());
    let mut seg = SegmentTree::<i32, _>::new(n, |x, y| std::cmp::min(x, y), 2147483647);

    for _ in 0..q {
        let (com, x, y): (usize, usize, usize) = (read(), read(), read());

        if com == 0 {
            seg.update(x, y as i32);
        } else {
            println!("{}", seg.query(x, y + 1));
        }
    }
}