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

import scala.annotation.tailrec
import net.pushl.io.MyConsole

package net.pushl {
  package number {
    // Prime    (Prime.scala)
    // Number   (Number.scala)
    // Combi    (Combi.scala)
    // Optimize (Optimize.scala)
  }
  package string {
    // RollingHash (RollingHash.scala)
  }
  package geometry {
    // Point   (Geometry.scala)
    // Segment (Geometry.scala)
    // Line    (Geometry.scala)
  }
  package datastructure {
    // UnionFindTree (UnionFind.scala)
  }
  package io {
  }
}


package net.pushl.datastructure {
  import scala.reflect.ClassTag
  abstract class ASegmentTree[T: ClassTag](_n: Int) {
    protected def init: T
    protected def calc(left: T, right: T): T
    private val n = smallest2Powered(_n)
    private val data = {
      val d = implicitly[ClassTag[T]].newArray(2*n-1)
      (0 until d.length).foreach(d(_) = init)
      d
    }
    def update(i: Int, v: T) : Unit = {
      val k = i+n-1
      data(k) = v
      @tailrec
      def updateAux(k: Int) : Unit =
        if(k > 0) {
          val p   = parent(k)
          data(p) = calc(data(getLeft(p)),data(getRight(p)))
          updateAux(p)
        }
      updateAux(k)
    }
    // get data of [a,b)
    def get(a: Int, b: Int) : T = get(a,b,0,0,n)

    // l,r is segment of node k.
    protected def get(a: Int, b: Int, k: Int, l: Int, r: Int) : T = {
      if(r <= a || b <= l) init
      else if(a <= l && r <= b) data(k)
      else calc(get(a,b,getLeft(k) ,l,(l+r)/2),
                get(a,b,getRight(k),(l+r)/2,r))
    }

    final private def getLeft (i: Int) = 2*i+1
    final private def getRight(i: Int) = 2*i+2
    final private def parent  (i: Int) = (i-1)/2
    final private def smallest2Powered(n: Int) = {
      @tailrec
      def smallest2PoweredAux(k: Int) : Int = {
        if(k >= n) k
        else smallest2PoweredAux(k*2)
      }
      smallest2PoweredAux(1)
    }
    override def toString() = data.foldLeft("[")(_ + "," + _) + "]"
  }
  class RangeSumQueryTree[T: ClassTag](n: Int)(implicit num: Numeric[T])
                                               extends ASegmentTree[T](n) {
    override def init = num.zero
    override def calc(left: T, right: T) = num.plus(left,right)
  }
  // Numeric does not have INF.
  class RangeMinimumQueryTree(n: Int) extends ASegmentTree[Int](n) {
    override def init = (1 << 31) - 1
    override def calc(left: Int, right: Int) = left min right
  }
}

// Document: http://www.scala-lang.org/api/current/#package
// -----------------------------------------------------------------------------
import net.pushl.datastructure.RangeMinimumQueryTree
class Solver(val stdio: MyConsole){
  import stdio._ // shadow Console.~
  def main() : Unit = {
    val n,q = nextInt
    val rmq = new RangeMinimumQueryTree(n)
    for(i <- 1 to q){
      val com,x,y = nextInt
      if(com == 0){
        rmq(x) = y
      } else {
        println(rmq.get(x,y+1))
      }
    }
  }
}









// ----------------------------------------------------------------------------0
// ----------------------------------------------------------------------------0
object Main {
  def main(args: Array[String]) : Unit = {
    val console = new MyConsole(Console.in, Console.out, Console.err)
    val solver  = new Solver(console)
    solver.main()
    console.flush()
  }
}
package net.pushl.io {
  import java.io.{BufferedReader, PrintWriter, PrintStream, PushbackReader}
  class MyConsole(val in: BufferedReader, val _out: PrintStream,
                  val err: PrintStream) {
    // PrintWriter do not flush automatically
    val out = new PrintWriter(_out,false)
    // If argument is null, there are ambiguous which function will be called
    def print(obj: Any)                  = out.print(if(obj == null) "null" else obj.toString)
    def println()                        = out.println()
    def println(obj: Any)                = out.println(obj)
    def printf(text: String, args: Any*) = out.printf(text.format(args : _*))
    // NOTE: YOU MUST FLUSH BEFORE END OF MAIN
    def flush()                          = out.flush()
    def debugln(obj: Any)                = err.println(obj)

    def readIntVector()    : Vector[Int]    = parseLineToVector(() => nextInt)
    def readLongVector()   : Vector[Long]   = parseLineToVector(() => nextLong)
    def readStringVector() : Vector[String] = parseLineToVector(() => nextString)
    def nextInt()          : Int            = nextLong().toInt
    def nextBigInt()       : BigInt         = BigInt(nextString())
    def nextBigDecimal(  ) : BigDecimal     = BigDecimal(nextString())
    def nextDouble()       : Double         = nextString().toDouble
    def nextLong() : Long = {
      if(!goNextValuable())
        throw new NoSuchElementException("Reading long failed")
      val sgn = if(peek == '-') -1l else 1
      if(sgn == -1l) read()
      if(peek < '0' || '9' < peek)
        throw new NumberFormatException(s"readLong found only '-' or no number")
      @tailrec
      def readLong(next: Int, cur: Long) : Long =
        if('0' <= next && next <= '9')
          readLong(readWithoutCheckingPeeked(), cur*10 + next-'0')
        else if(isEnd(next) || isSpaceOrControl(next))
          sgn*cur
        else
          throw new NumberFormatException(s"readLong found strange byte $next")
      val res = readLong(read(),0)
      skipTrailingSpaces()
      res
    }
    def nextString() : String = {
      if(!goNextValuable())
        throw new NoSuchElementException("Reading String failed")
      val builder = new StringBuilder
      @tailrec
      def appendCode(next: Int) : String = {
        if(isEnd(next) || isSpaceOrControl(next)){
          builder.toString
        }else{
          builder.append(next.toChar)
          appendCode(readWithoutCheckingPeeked())
        }
      }
      val res = appendCode(read())
      skipTrailingSpaces()
      res
    }
    // TODO: refactoring to marge nextString
    def readLine() : String = {
      if(isEnd(peek))
        throw new NoSuchElementException("Reading Line failed")
      val builder = new StringBuilder
      @tailrec
      def appendCode(next: Int) : String = {
        if(isEnd(next) || isNewLine(next)){
          builder.toString
        }else{
          builder.append(next.toChar)
          appendCode(read())
        }
      }
      appendCode(read())
    }
    // helpers
    private[this] var peeked: Option[Int] = None
    private[this] var last = -1
    private def read() = {
      val res = peeked match {
          case None    => in.read()
          case Some(a) => { peeked = None; a }
        }
      last = res
      res
    }
    @inline private def readWithoutCheckingPeeked() = {
      val res = in.read()
      last = res
      res
    }
    @inline private def peek() =
      peeked match {
        case None    => {
          val res = in.read()
          peeked  = Some(res)
          res
        }
        case Some(a) => a
      }
    @inline private def isEnd(c: Int)    = c == -1
    @inline private def isNewLine(c: Int) = c == 10 || c == 13     // LF and CR
    @inline private def isThereReadable() = !isEnd(peek)
    // XXX: this limits c is ASCII?
    @inline private def isSpaceOrControl(c: Int) = (0 <= c && c <= 32) || c == 127
    @tailrec
    final private def goNextNotSpaceNorControl() : Unit =
      if(isSpaceOrControl(peek)){
        read()
        goNextNotSpaceNorControl()
      }
    final private def skipTrailingSpaces() : Unit = {
      @tailrec
      def skipTrailingSpacesAux() : Unit = {
        if(!isNewLine(last) && !isNewLine(peek) && isSpaceOrControl(peek)){
          read()
          skipTrailingSpacesAux()
        }
      }
      skipTrailingSpacesAux
      if(!isNewLine(last) && isNewLine(peek)) {
        val _ = read()
      }
    }
    @tailrec
    final private def skipTrailingSpacesAndNewline() : Unit =
      if(isNewLine(peek)){
        val _ = read() // windows causes error. maybe.
      }else if(isSpaceOrControl(peek)){
        read()
        skipTrailingSpacesAndNewline()
      }
    @inline private def goNextValuable() = {
      goNextNotSpaceNorControl()
      isThereReadable()
    }
    @inline private def parseLineToVector[X](parser: () => X) : Vector[X] = {
      import scala.collection.immutable.VectorBuilder
      val vb = new VectorBuilder[X]()
      @tailrec
      def parseLineToVectorAux(first: Boolean=false) : Vector[X] =
        if((!first && isNewLine(last)) || isNewLine(peek) || isEnd(peek)) {
          vb.result
        }else{
          vb += parser()
          parseLineToVectorAux()
        }
      parseLineToVectorAux(true)
    }
  }
}