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)

//{{{
#[allow(unused_macros)]
macro_rules! getl {
    ( $( $t:ty ),* ) => {
        {
            let mut s = String::new();
            std::io::stdin().read_line(&mut s).unwrap();
            let s = s.trim_right();
            let mut ws = s.split_whitespace();
            ($(ws.next().unwrap().parse::<$t>().unwrap()),*)
        }
    };
}

#[allow(unused_macros)]
macro_rules! getl_vec {
    ( $t:ty ) => {{
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        let s = s.trim_right();
        s.split_whitespace()
            .map(|x| x.parse().unwrap())
            .collect::<Vec<$t>>()
    }};
}
//}}}

const INF: u64 = (1 << 31) - 1;

fn main() {
    const UPDATE: u64 = 0;
    const FIND: u64 = 1;

    let (n, q) = getl!(usize, usize);
    let mut queries = vec![];
    for _ in 0..q {
        queries.push(getl!(u64, u64, u64));
    }

    let mut segtree = SegmentTree::new(&vec![INF; n], std::cmp::min, INF);
    for (ty, a, b) in queries {
        if ty == UPDATE {
            segtree.update(a as usize, b);
        } else {
            let ans = segtree.query(a as usize, b as usize + 1);
            println!("{}", ans);
        }
    }
}

struct SegmentTree<T, F>
where
    F: Fn(T, T) -> T + Copy,
    T: Clone + Copy,
{
    len: usize,
    data: Vec<T>,
    operator: F,
    unit: T,
}

impl<T, F> SegmentTree<T, F>
where
    F: Fn(T, T) -> T + Copy,
    T: Clone + Copy,
{
    // const INF: u64 = std::u64::MAX >> 2;

    fn new(v: &Vec<T>, operator: F, unit: T) -> SegmentTree<T, F> {
        let n = v.len();
        let mut len = 1;
        while len < n {
            len *= 2;
        }

        let mut segtree = SegmentTree {
            len: len,
            data: vec![unit; 2 * len - 1],
            operator: operator,
            unit: unit,
        };

        for i in 0..n {
            segtree.data[i + segtree.len - 1] = v[i];
        }
        for i in (0..(segtree.len - 1)).rev() {
            segtree.data[i] = operator(segtree.data[2 * i + 1], segtree.data[2 * i + 2]);
        }

        segtree
    }

    fn update(&mut self, k: usize, a: T) {
        let data = &mut self.data;
        let mut k = k + self.len - 1;
        data[k] = a;
        while k > 0 {
            k = (k - 1) / 2;
            data[k] = (self.operator)(data[k * 2 + 1], data[k * 2 + 2]);
        }
    }

    fn query(&self, a: usize, b: usize) -> T {
        self.process_query(a, b, 0, 0, self.len)
    }

    fn process_query(&self, a: usize, b: usize, k: usize, l: usize, r: usize) -> T {
        if r <= a || b <= l {
            return self.unit;
        }

        if a <= l && r <= b {
            self.data[k]
        } else {
            let vl = self.process_query(a, b, k * 2 + 1, l, (l + r) / 2);
            let vr = self.process_query(a, b, k * 2 + 2, (l + r) / 2, r);
            (self.operator)(vl, vr)
        }
    }
}