Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Union of Rectangles

Given a set of $N$ axis-aligned rectangles in the plane, find the area of regions which are covered by at least one rectangle.

Input

The input is given in the following format.

$N$

$x1_1$ $y1_1$ $x2_1$ $y2_1$

$x1_2$ $y1_2$ $x2_2$ $y2_2$

:

$x1_N$ $y1_N$ $x2_N$ $y2_N$

($x1_i, y1_i$) and ($x2_i, y2_i$) are the coordinates of the top-left corner and the bottom-right corner of the $i$-th rectangle respectively.

Constraints

$ 1 \leq N \leq 2000 $

$ −10^9 \leq x1_i < x2_i\leq 10^9 $

$ −10^9 \leq y1_i < y2_i\leq 10^9 $

Output

Print the area of the regions.

Sample Input 1

2
0 0 3 4
1 2 4 3

Sample Output 1

13

Sample Input 2

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

Sample Output 2

7

Sample Input 3

4
0 0 3 1
0 0 1 3
0 2 3 3
2 0 3 3

Sample Output 3

8

Solution in Scala (judge verdict: Accepted)

import java.util.Scanner

object Main extends App { 
  val sc = new Scanner(System.in)
  val n  = sc.nextInt()
  val list = (for (i <- 0 until n) yield (i, sc.nextLong(), sc.nextLong(), sc.nextLong(), sc.nextLong())).toList
 
  type XAux = (Int, Int, Long, Long, Long) // (id, state, x aux, top, bottom)
  type YAux = (Int, Int, Long) // (id, state, y aux)

  val xlist = (for ((i,l,t,r,b) <- list) yield List((i,0,l,t,b), (i,1,r,t,b))).flatten.sortBy(_._3)

  def area(x:Long, p:Long, ylist:List[YAux]):Long = {
    def iter(yl:List[YAux], c:Int, p:Long, ac:Long):Long = {
      if (yl.isEmpty) ac
      else {
        val (i,s,y) = yl.head
        (s, c) match {
          case (0, 0) => iter(yl.tail, c+1, y, ac)
          case (0, _) => iter(yl.tail, c+1, p, ac)
          case (1, 1) => iter(yl.tail, c-1, p, ac+y-p)
          case (_, _) => iter(yl.tail, c-1, p, ac)
        }
      }
    }
    iter(ylist.sortBy(_._3), 0, 0, 0)*(x-p)
  }

  def solver(xl:List[XAux], yl:List[YAux], c:Int, p:Long, acc:Long):Long = {
    def addRect(yl:List[YAux], xr:XAux):List[YAux] = {
      val (i,s,x,t,b) = xr
      if (b < t) (i,0,b)::(i,1,t)::yl else (i,0,t)::(i,1,b)::yl
    } 

    if (xl.isEmpty) acc
    else {
      val (i, s, x, t, b) = xl.head
      (s, c) match {
        case (0, 0) => solver(xl.tail, addRect(yl, xl.head), c+1, x, acc)
        case (0, _) => solver(xl.tail, addRect(yl, xl.head), c+1, x, acc+area(x, p, yl))
        case (_, _) => solver(xl.tail, yl.filter(_._1 != i), c-1, x, acc+area(x, p, yl))
      }
    } 
  }

  println(solver(xlist, Nil, 0, 0, 0))
}