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

//https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 より
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

// ここまで

fn run() {
    input! {
        n: usize,
        p: [(i64, i64, i64, i64); n],
    }
    let mut x = Vec::with_capacity(2 * n);
    let mut y = Vec::with_capacity(2 * n);
    for p in p.iter() {
        x.push(p.0);
        x.push(p.2);
        y.push(p.1);
        y.push(p.3);
    }
    x.sort();
    x.dedup();
    y.sort();
    y.dedup();
    let mut add = vec![vec![]; x.len()];
    let mut sub = vec![vec![]; x.len()];
    for (a, b, c, d) in p {
        let a = x.binary_search(&a).unwrap();
        let b = y.binary_search(&b).unwrap();
        let c = x.binary_search(&c).unwrap();
        let d = y.binary_search(&d).unwrap();
        add[a].push((b, d));
        sub[c].push((b, d));
    }
    let mut ans = 0;
    let mut dp = vec![0; y.len()];
    for i in 0..(x.len() - 1) {
        let mut imos = vec![0; y.len()];
        for p in add[i].iter() {
            imos[p.0] += 1;
            imos[p.1] -= 1;
        }
        for p in sub[i].iter() {
            imos[p.0] -= 1;
            imos[p.1] += 1;
        }
        for j in 1..y.len() {
            imos[j] += imos[j - 1];
        }
        for (dp, imos) in dp.iter_mut().zip(imos.iter()) {
            *dp += *imos;
        }
        let h = x[i + 1] - x[i];
        for j in 0..(y.len() - 1) {
            if dp[j] > 0 {
                ans += h * (y[j + 1] - y[j]);
            }
        }
    }
    println!("{}", ans);
}

fn main() {
    run();
}