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 JAVA (judge verdict: Runtime Error)

import java.util.Scanner;

class Node{
	int Hcover;
	int Lcover; 
	int min;
	Node parent;
	Node left;
	Node right;
	public Node(){
		parent=null;
		left=null;
		right=null;
	}
	
	public Node(int l,int h,int m){
		Hcover=h;
		Lcover=l;
		min=m;
		parent=null;
		left=null;
		right=null;
	}

	public boolean between(int a){
		return (Lcover<=a)&&(a<=Hcover);
	}
}

public class Main {
	static Node table[]=new Node[100001];

	public static Node cousei(Node n,int l,int h,int m){
		Node mob=new Node(h,l,m);
		mob.parent=n;
		if(h>l){
			mob.left=cousei(mob,l, (h+l)/2, m);
			mob.right=cousei(mob,(h+l)/2+1, h, m);
		}
		if(h==l) table[h]=mob;
		return mob;
	}

	public static int find(Node n,int l,int h){
		//System.out.println("f:"+n.Lcover+"to"+n.Hcover+":"+n.min+"::"+l+"to"+h);
		if(n.Lcover==l&&n.Hcover==h)return n.min;

		if(n.left.between(l)&&n.left.between(h)){
			return find(n.left, l, h);
		}else if(n.right.between(l)&&n.right.between(h)){
			return find(n.right, l, h);
		}else{
			return Math.min(find(n.left, l, n.left.Hcover), find(n.right, n.right.Lcover,h));
		}
	}

	public static void update(Node n,int p,int x,int bef){
		for(Node it=n;it!=null;it=it.parent){
				it.min=Math.min(it.left.min, it.right.min);
		}
	}
	public static void prin(Node n){
		//System.out.println(n.Lcover+"to"+n.Hcover+":"+n.min);
		if(n.Hcover==n.Lcover)return;
		prin(n.left);
		prin(n.right);
	}

	public static void main(String[] args) {
		Node root=new Node();
		int n;
		int q;
		Scanner stdin=new Scanner(System.in);
		n=stdin.nextInt();
		q=stdin.nextInt();
		root.min=(1<<31)-1;
		root.Hcover=n;
		root.Lcover=1;
		root.parent=null;
		root.left=cousei(root,1,(n+1)/2,root.min);
		root.right=cousei(root,(n+1)/2+1,n,root.min);
		for(int XXX=0;XXX<q;XXX++){
			int com=stdin.nextInt();
			int x=stdin.nextInt();
			int y=stdin.nextInt();
			x++;
			if(com==0){
				// update
				int m=table[x].min;
				table[x].min=y;
				update(table[x].parent, x, y,m);
				prin(root);
			}else{
				// find
				y++;
				System.out.println(find(root, x, y));
			}
		}
		stdin.close();
	}

}