Problem:
Score : 400 points

Problem Statement

There are N one-off jobs available. If you take the i-th job and complete it, you will earn the reward of B_i after A_i days from the day you do it.

You can take and complete at most one of these jobs in a day.

However, you cannot retake a job that you have already done.

Find the maximum total reward that you can earn no later than M days from today.

You can already start working today.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq A_i \leq 10^5

1 \leq B_i \leq 10^4

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
A_2 B_2
\vdots
A_N B_N

Output

Print the maximum total reward that you can earn no later than M days from today.

Sample Input 1

3 4
4 3
4 1
2 2

Sample Output 1

5

You can earn the total reward of 5 by taking the jobs as follows:

Take and complete the first job today. You will earn the reward of 3 after four days from today.

Take and complete the third job tomorrow. You will earn the reward of 2 after two days from tomorrow, that is, after three days from today.

Sample Input 2

5 3
1 2
1 3
1 4
2 1
2 3

Sample Output 2

10

Sample Input 3

1 1
2 1

Sample Output 3

0

Solution in Scala (2.11.7) (judge verdict: Wrong Answer)


import scala.reflect._

sealed trait IndexOf {
  def index: Int
}
case class Contains(index: Int) extends IndexOf
case class InsertedTo(index: Int) extends IndexOf


object SortedArrayList {

  val DefaultCapacity = 1000

  def apply[A](capacity: Int)(implicit ordering: Ordering[A], tag: ClassTag[A]): SortedArrayList[A] = {
    new SortedArrayList(new Array(capacity))
  }

  
  def apply[A,S](by: A => S)(implicit ordering: Ordering[S], tag: ClassTag[A]): SortedArrayList[A] = {
    new SortedArrayList[A](new Array(DefaultCapacity))(Ordering.by(by), tag)
  }
  def apply[A,S](capacity:Int, by: A => S)(implicit ordering: Ordering[S], tag: ClassTag[A]): SortedArrayList[A] = {
    new SortedArrayList[A](new Array(capacity))(Ordering.by(by), tag)
  }

}

class SortedArrayList[A](protected var innerArray: Array[A])(implicit ordering: Ordering[A], tag: ClassTag[A]){

  protected var length = 0;
  var expandRate = 2.0
  def capacity = innerArray.length

  def size() = length

  def apply(index: Int) = {
    innerArray(index)
  }

  def range(minInclude: A, maxInclude: A): Array[A] = {
    (indexOf(minInclude),indexOf(maxInclude)) match {
      case (Contains(start),Contains(end)) => {
        innerArray.slice(start, end+1)
      }
      case (Contains(start),InsertedTo(end)) => {
        innerArray.slice(start, end)
      }
      case (InsertedTo(start),Contains(end)) => {
        innerArray.slice(start, end + 1)
      }
      case (InsertedTo(start),InsertedTo(end)) => {
        innerArray.slice(start, end)
      }
    }
  }

  def rangeInEx(minInclude: A, maxExclude: A): Array[A] = {
    (indexOf(minInclude),indexOf(maxExclude)) match {
      case (Contains(start),Contains(end)) => {
        innerArray.slice(start, end)
      }
      case (Contains(start),InsertedTo(end)) => {
        innerArray.slice(start, end)
      }
      case (InsertedTo(start),Contains(end)) => {
        innerArray.slice(start, end)
      }
      case (InsertedTo(start),InsertedTo(end)) => {
        innerArray.slice(start, end)
      }
    }
  }
  
  def indexOf(elem: A): IndexOf = {
    if(length == 0) {
      return InsertedTo(0)
    }

    val index = if(tag == classTag[Int]) {
      java.util.Arrays.binarySearch(
        innerArray.asInstanceOf[Array[Int]],
        0, length,
        elem.asInstanceOf[Int]
      )
    } else if(tag == classTag[Long]) {
      java.util.Arrays.binarySearch(
        innerArray.asInstanceOf[Array[Long]],
        0, length,
        elem.asInstanceOf[Long]
      )
    } else {
      java.util.Arrays.binarySearch(
        innerArray.asInstanceOf[Array[Object]],
        0, length,
        elem.asInstanceOf[Object],
        ordering.asInstanceOf[java.util.Comparator[Object]]
      )
    }
    if(index >= 0) {
      Contains(index)
    } else {
      InsertedTo( -(index + 1))
    }
  }

  def +=(elem: A): this.type = {
    insertTo(indexOf(elem).index, elem)
    //println(s"Insert ${elem} to ${indexOf(elem)}")
    this
  }


  protected def insertTo(index: Int, elem: A) = {
    if(length == capacity) {
      val expandedArray = new Array[A]((length * expandRate).toInt)
      innerArray.copyToArray(expandedArray)
      innerArray = expandedArray
    }
    for {
      i <- (length - 1) to index by -1
    } {
      innerArray(i + 1) = innerArray(i)
    }
    innerArray(index) = elem
    length += 1
  }

  def addIfNotContains(elem: A): Boolean = {
    indexOf(elem) match {
      case Contains(index) => false
      case InsertedTo(index) => {
        insertTo(index, elem)
        true
      }
    }
  }

  def -=(elem: A) = {
    indexOf(elem) match {
      case Contains(index) => {
        removeAt(index)
        true
      }
      case _ => false
    }
  }

  def removeAt(index: Int) = {
    for {
      i <- index until length - 1
    } {
      innerArray(i) = innerArray(i + 1)
    }
    length -= 1

  }
  
  def removeEq(elem: A): Boolean = {
    indexOf(elem) match {
      case Contains(index) => {
        for {
          i <- index until length
        } {
          if(innerArray(index) == elem) {
            removeAt(i)
            return true
          }
        }
        return false
      }
      case InsertedTo(index) => false
    }
  }

  def toArray = {
    innerArray.slice(0, length)
  }

  def toList = {
    toArray.toList
  }


}

class SortedArrayMap[K,V](array: Array[(K,V)])(implicit ordering: Ordering[K], classTag: ClassTag[(K,V)]) extends SortedArrayList[(K,V)](array)(
  new Ordering[(K,V)]() {
    def compare(x: (K,V), y: (K,V)): Int = {
      ordering.compare(x._1, y._1)
    }
  }, classTag
) {
  override def +=(elem: (K,V)) = {
    indexOf(elem) match {
      case Contains(index) => this
      case InsertedTo(index) => {
        innerArray(index) = elem
        this
      }
    }
  }
}

object Main {

  def main(args: Array[String]): Unit = {

    val Array(n,m) = scala.io.StdIn.readLine().split(" ").map(_.toInt)


    val arbeiten: SortedArrayList[(Int,Int)] = SortedArrayList(n, t => t._1)
    (0 until n)
      .map(_ => {
        val Array(day,reward) = readLine().split(" ").map(_.toInt)
        arbeiten += (day, reward)
      })

    val availables: SortedArrayList[Int] = SortedArrayList(n)

    // val arbeiten = Array(0,0) :: (0 until n)
    //   .map(_ => scala.io.StdIn.readLine().split(" ").map(_.toInt)).toList
    

    val totalReward = (for { 
      leftDays <- 0 to m
    } yield {
      val add = arbeiten.rangeInEx((leftDays,0),(leftDays + 1,0))
      for {
        v <- add
      } {
        availables += v._2
      }
      println(s"Day:${leftDays} ${availables.toList}")
      if(availables.size() == 0) {
        0
      } else {
        val v = availables(availables.size() - 1)
        availables.removeAt(availables.size() - 1)
        v
      }
    }).sum

    println(totalReward)
  }

}