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 OCaml (judge verdict: Accepted)

open Printf open Scanf
module Lib = struct
	let i32,i64,ist = Int64.(to_int,of_int,to_string)
	let (+$) = (+) let (-$) = (-) let (/$) = (/) let ( *$) = ( * ) let (%$) = (mod)
	let labs = Int64.abs
	let (+),(-),( * ),(/),(mod),(%) = Int64.(add,sub,mul,div,rem,rem)
	let (+=) r v = r := !r + v
	let (-=) r v = r := !r - v
	let ( *= ) r v = r := !r * v
	let (/=) r v = r := !r / v
	let (%=) r v = r := !r % v
	let max_i64,min_i64 = Int64.(max_int,min_int)
	(* math *)
	let ceildiv p q = (p+q-1L) / q
	let rec gcd m n = match m,n with | m,0L -> m | m,n -> gcd n (m mod n)
	let lcm m n = m / gcd m n * n 
	module I64_infix = struct
		let (land),(lor),(lxor),lnot,(lsl),(lsr),(asr) =
			let open Int64 in
			(logand),(logor),(logxor),lognot,
			(fun u v -> shift_left u (i32 v)),
			(fun u v -> shift_right u (i32 v)),
			(fun u v -> shift_right_logical u (i32 v))
	end
	(* input *)
	let input_i64_array n = Array.init (i32 n) (fun _ -> Scanf.scanf " %Ld" (fun v -> v))
	let get_i64 _ = Scanf.scanf " %Ld" (fun v -> v)
	let get_2_i64 _ = Scanf.scanf " %Ld %Ld" (fun u v -> u,v)
	let get_3_i64 _ = Scanf.scanf " %Ld %Ld %Ld" (fun u v w -> u,v,w)
	let get_4_i64 _ = Scanf.scanf " %Ld %Ld %Ld %Ld" (fun u v w x -> u,v,w,x)
	let get_5_i64 _ = Scanf.scanf " %Ld %Ld %Ld %Ld %Ld" (fun u v w x y -> u,v,w,x,y)
	let i32_get_int _ = Scanf.scanf " %d" (fun v -> v) let i32_get_2_ints _ = Scanf.scanf " %d %d" (fun u v -> u,v) let i32_get_3_ints _ = Scanf.scanf " %d %d %d" (fun u v w -> u,v,w) let i32_get_4_ints _ = Scanf.scanf " %d %d %d %d" (fun u v w x -> u,v,w,x) let i32_get_5_ints _ = Scanf.scanf " %d %d %d %d %d" (fun u v w x y -> u,v,w,x,y)
	(* utils *)
	external id : 'a -> 'a = "%identity"
	let ( *< ) f g x = f (g x)
	let ( *> ) f g x = g (f x)
	let rv f p q = f q p (* ex. 24 |> rv (/) 6 *)
	let alen a = i64 @@ Array.length a
	let llen l = i64 @@  List.length l
	let string_of_list ?(separator=" ") f ls = ls |> List.map f |> String.concat separator
	let string_of_array ?(separator=" ") f a = a |> Array.to_list |> string_of_list ~separator f
	let char_list_of_string str = let rec f0 i a = if i<0 then a else f0 (i-$1) (str.[i]::a) in f0 (String.length str -$ 1) []
	let string_of_char_list ls = List.fold_left (fun u v -> u ^ (String.make 1 v)) "" ls
	let fail _ = failwith "fail"
	let dx,dy = [|1;0;-1;0|],[|0;1;0;-1|]
	let range l r = let ls = ref [] in for i=i32 l to i32 r do ls := i :: !ls done;!ls |> List.rev
	let cartesian_product u v = u |> List.map (fun p -> List.map (fun q -> p,q) v) |> List.flatten
	let shuffle a = Array.sort (fun _ _ -> (Random.int 3) -$ 1) a
	let binary_search ng ok f = let d = if ng < ok then 1L else -1L in
		let rec f0 ng ok =
			if labs (ok - ng) <= 1L then ok
			else let mid = ng + (ok - ng) / 2L in if f mid then f0 ng mid else f0 mid ok
		in f0 (ng-1L*d) (ok+1L*d)
	let lower_bound a v = binary_search 0L (alen a - 1L) (fun i -> a.(i32 i) >= v)
	let upper_bound a v = binary_search 0L (alen a - 1L) (fun i -> a.(i32 i) >  v)
	let equal_range a v = lower_bound a v, upper_bound a v (* #=snd-fst *)
	let rec fix f x = f (fix f) x
	let fix_memo ?(size=10000) f x =
		let tb = Hashtbl.create ~random:true size in
		let rec f0 x =
			try Hashtbl.find tb x with
			| Not_found -> (let v = f f0 x in Hashtbl.add tb x v; v)
		in f0 x
	(* imperative *)
	let rep f t ?(stride=1L) fbod = let i = ref f in while !i <= t do fbod !i; i := !i + stride done
	let repb f t ?(stride=1L) fbod = let i,c = ref f,ref true in while !i <= t && !c do
		match fbod !i with | `Break -> c := false | `Ok -> i := !i + stride done
	let repm f t ?(stride=1L) m0 fbod =
		let i,c,m = ref f,ref true,ref m0 in
		while !i<=t && !c do match fbod !m !i with
		| `Break -> c := false | `Break_m m' -> (c := false; m := m') | `Ok m' -> m := m'; i := !i + stride done; !m
	let repi f t ?(stride=1) fbod = let i = ref f in while !i <= t do fbod !i; i := !i +$ stride done
	let repib f t ?(stride=1) fbod = let i,c = ref f,ref true in while !i <= t && !c do
		match fbod !i with | `Break -> c := false | `Ok -> i := !i +$ stride done
	let repim f t ?(stride=1) m0 fbod =
		let i,c,m = ref f,ref true,ref m0 in
		while !i<=t && !c do match fbod !m !i with
		| `Break -> c := false | `Break_m m' -> (c := false; m := m') | `Ok m' -> m := m'; i := !i +$ stride done; !m
	let rep_rev f t ?(stride=1L) fbod = rep t f ~stride @@ fun v -> fbod @@ f + t - v
	let repb_rev f t ?(stride=1L) fbod = repb t f ~stride @@ fun v -> fbod @@ f + t - v
	let repm_rev f t ?(stride=1L) m0 fbod = repm f t ~stride m0 @@ fun u v -> fbod u @@ f + t - v
	let repi_rev f t ?(stride=1) fbod = repi t f ~stride @@ fun v -> fbod @@ f +$ t -$ v
	let repib_rev f t ?(stride=1) fbod = repib t f ~stride @@ fun v -> fbod @@ f +$ t -$ v
	let repim_rev f t ?(stride=1) m0 fbod = repim f t ~stride m0 @@ fun u v -> fbod u @@ f +$ t -$ v
	(* output *)
	let print_list_mle f ls = string_of_list f ls |> print_endline
	let print_array_mle f a = string_of_array f a |> print_endline
	let print_list f ls = ls |> List.iter (fun v -> printf "%s " @@ f v); print_newline ()
	let print_array f a = a |> Array.iter (fun v -> printf "%s " @@ f v); print_newline ()
	(* debug *)
	let dump_2darr f a = a |> Array.iter (fun b -> print_array f b)
	let dump_i64_list ls = print_list ist ls
	let dump_i64_array a = print_array ist a
end open Lib open Array

module SegTree = struct
	module type S = sig
		type t
		val  op: t -> t -> t
		val def: t
	end
	module RMQ = struct type t = int64 let op = min let def = max_i64 end
	let par i = (i-$1)/$2
	let chl i = 2*$i+$1
	let chr i = 2*$i+$2
	module Make (X:S) = struct
		type t = SegTree of (X.t array * int)
		let raw (SegTree (a,_)) = a
		let make raw =
			let ln = Array.length raw in
			let n =
				let n = ref 1 in
				while !n<ln do n := !n*$2 done; !n in
			let a = Array.make (2*$n-$1) X.def in
			for i=0 to ln-$1 do
				a.(i+$n-$1) <- raw.(i) done;
			for i=n-$2 downto 0 do
				a.(i) <- X.op a.(chl i) a.(chr i) done;
			SegTree (a,n)
		let update_destructive (SegTree(a,n)) i v = 
			let i = ref @@ i+$(n-$1) in a.(!i) <- v;
			while !i>0 do
				i := par !i;
				a.(!i) <- X.op a.(chl !i) a.(chr !i) done
		let get_half_open (SegTree(a,n)) l r = (* [l,r) *)
			let rec f0 i p q =
				if q<=l || r<=p then X.def
				else if l<=p && q<=r then a.(i)
				else
					let vl = f0 (2*$i+$1) p ((p+$q)/$2) in
					let vr = f0 (2*$i+$2) ((p+$q)/$2) q in
					X.op vl vr
			in f0 0 0 n
		let get_closed seg l r = get_half_open seg l (r+$1) (* [l,r] *)
	end
end

module RMQ = SegTree.Make(SegTree.RMQ)
let () =
	let n,q = get_2_i64 0 in
	let a = RMQ.make (make (i32 n) (i64 (2 lsl 30) - 1L)) in
	rep 1L q (fun _ ->
		let com,x,y = get_3_i64 0 in
		if com = 0L then (
			RMQ.update_destructive a (i32 x) y
		) else (
			printf "%Ld\n" @@ RMQ.get_closed a (i32 x) (i32 y)
		)
	)