Problem:
Score : 700 points

Problem Statement

There are N bags, each containing two white balls. The i-th box contains two balls with integers x_i and y_i written on them, respectively.

For each of these bags, you will paint one of the balls red, and paint the other blue.

Afterwards, the 2N balls will be classified according to color.

Then, we will define the following:

R_{max}: the maximum integer written on a ball painted in red

R_{min}: the minimum integer written on a ball painted in red

B_{max}: the maximum integer written on a ball painted in blue

B_{min}: the minimum integer written on a ball painted in blue

Find the minimum possible value of (R_{max} - R_{min}) \times (B_{max} - B_{min}).

Constraints

1 ≤ N ≤ 200,000

1 ≤ x_i, y_i ≤ 10^9

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_N y_N

Output

Print the minimum possible value.

Sample Input 1

3
1 2
3 4
5 6

Sample Output 1

15

The optimal solution is to paint the balls with x_1, x_2, y_3 red, and paint the balls with y_1, y_2, x_3 blue.

Sample Input 2

3
1010 10
1000 1
20 1020

Sample Output 2

380

Sample Input 3

2
1 1
1000000000 1000000000

Sample Output 3

999999998000000001

Solution in Rust (1.42.0) (judge verdict: Accepted)

pub trait Zero: PartialEq + Sized {
    fn zero() -> Self;
    #[inline]
    fn is_zero(&self) -> bool {
        self == &Self::zero()
    }
}
pub trait One: PartialEq + Sized {
    fn one() -> Self;
    #[inline]
    fn is_one(&self) -> bool {
        self == &Self::one()
    }
}
macro_rules !zero_one_impls {($({$Trait :ident $method :ident $($t :ty ) *,$e :expr } ) *) =>{$($(impl $Trait for $t {#[inline ] fn $method () ->Self {$e } } ) *) *} ;}
zero_one_impls !({Zero zero u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 ,0 } {Zero zero f32 f64 ,0. } {One one u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 ,1 } {One one f32 f64 ,1. } ) ;
pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
impl<'a> Scanner<'a> {
    #[inline]
    pub fn new(s: &'a str) -> Self {
        let iter = s.split_ascii_whitespace();
        Self { iter }
    }
    #[inline]
    pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
        T::scan(&mut self.iter).unwrap()
    }
    #[inline]
    pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
        marker.mscan(&mut self.iter).unwrap()
    }
    #[inline]
    pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
        (0..size)
            .map(|_| T::scan(&mut self.iter).unwrap())
            .collect()
    }
    #[inline]
    pub fn scan_chars(&mut self) -> Vec<char> {
        self.iter.next().unwrap().chars().collect::<Vec<char>>()
    }
    #[inline]
    pub fn scan_chars_with(&mut self, base: char) -> Vec<usize> {
        self.iter
            .next()
            .unwrap()
            .chars()
            .map(|c| (c as u8 - base as u8) as usize)
            .collect::<Vec<usize>>()
    }
}
mod scanner_impls {
    use super::*;
    macro_rules !iter_scan_impls {($($t :ty ) *) =>{$(impl IterScan for $t {type Output =Self ;#[inline ] fn scan <'a ,I :Iterator <Item =&'a str >>(iter :&mut I ) ->Option <Self >{iter .next () ?.parse ::<$t >() .ok () } } ) *} ;}
    iter_scan_impls !(char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String ) ;
    macro_rules !iter_scan_tuple_impl {($($T :ident ) *) =>{impl <$($T :IterScan ) ,*>IterScan for ($($T ,) *) {type Output =($(<$T as IterScan >::Output ,) *) ;#[inline ] fn scan <'a ,It :Iterator <Item =&'a str >>(_iter :&mut It ) ->Option <Self ::Output >{Some (($($T ::scan (_iter ) ?,) *) ) } } } ;}
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl !(A B ) ;
    iter_scan_tuple_impl !(A B C ) ;
    iter_scan_tuple_impl !(A B C D ) ;
    iter_scan_tuple_impl !(A B C D E ) ;
    iter_scan_tuple_impl !(A B C D E F ) ;
    iter_scan_tuple_impl !(A B C D E F G ) ;
    iter_scan_tuple_impl !(A B C D E F G H ) ;
    iter_scan_tuple_impl !(A B C D E F G H I ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J K ) ;
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        fn next(&mut self) -> Option<Self::Item> {
            T::scan(&mut self.inner.iter)
        }
    }
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
}
pub mod marker {
    use super::*;
    pub struct Usize1;
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            usize::scan(iter).map(|x| x.wrapping_sub(1))
        }
    }
    pub struct Isize1;
    impl IterScan for Isize1 {
        type Output = isize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            isize::scan(iter).map(|x| x.wrapping_sub(1))
        }
    }
}
#[macro_export]
macro_rules !min {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::min ($e ,min !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmin {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::min ($dst ,min !($($src ) ,+) ) ;$dst =x ;} } ;}
#[macro_export]
macro_rules !max {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::max ($e ,max !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmax {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::max ($dst ,max !($($src ) ,+) ) ;$dst =x ;} } ;}
/// binary operaion: $T \circ T \to T$
pub trait Magma {
    /// type of operands: $T$
    type T: Clone + PartialEq;
    /// binary operaion: $\circ$
    fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T;
    #[inline]
    fn reverse_operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
        self.operate(x, y)
    }
}
/// $\forall a,\forall b,\forall c \in T, (a \circ b) \circ c = a \circ (b \circ c)$
pub trait Associative {}
/// associative binary operation
pub trait SemiGroup: Magma + Associative {}
impl<S: Magma + Associative> SemiGroup for S {}
/// $\exists e \in T, \forall a \in T, e \circ a = a \circ e = e$
pub trait Unital: Magma {
    /// identity element: $e$
    fn unit(&self) -> Self::T;
}
/// associative binary operation and an identity element
pub trait Monoid: SemiGroup + Unital {
    /// binary exponentiation: $x^n = x\circ\ddots\circ x$
    fn pow(&self, x: Self::T, n: usize) -> Self::T {
        let mut n = n;
        let mut res = self.unit();
        let mut base = x;
        while n > 0 {
            if n & 1 == 1 {
                res = self.operate(&res, &base);
            }
            base = self.operate(&base, &base);
            n = n >> 1;
        }
        res
    }
}
impl<M: SemiGroup + Unital> Monoid for M {}
/// $\exists e \in T, \forall a \in T, \exists b,c \in T, b \circ a = a \circ c = e$
pub trait Invertible: Magma {
    /// $a$ where $a \circ x = e$
    fn inverse(&self, x: &Self::T) -> Self::T;
}
/// short cut of right inverse binary operation
pub trait RightInvertibleMagma: Magma {
    /// right inverse binary operation: $\cdot \circ (\cdot^{-1})$
    fn rinv_operation(&self, x: &Self::T, y: &Self::T) -> Self::T;
}
/// associative binary operation and an identity element and inverse elements
pub trait Group: Monoid + Invertible {}
impl<G: Monoid + Invertible> Group for G {}
/// $\forall a,\forall b \in T, a \circ b = b \circ a$
pub trait Commutative {}
/// commutative monoid
pub trait AbelianMonoid: Monoid + Commutative {}
impl<M: Monoid + Commutative> AbelianMonoid for M {}
/// commutative group
pub trait AbelianGroup: Group + Commutative {}
impl<G: Group + Commutative> AbelianGroup for G {}
/// $\forall a \in T, a \circ a = a$
pub trait Idempotent {}
/// idempotent monoid
pub trait IdempotentMonoid: Monoid + Idempotent {}
impl<M: Monoid + Idempotent> IdempotentMonoid for M {}
/// binary operation to select smaller element
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct MinOperation<T: Clone + Ord + MaximumBounded> {
    _marker: std::marker::PhantomData<fn() -> T>,
}
pub trait MaximumBounded {
    fn maximum() -> Self;
}
mod min_operation_impl {
    use super::*;
    macro_rules !impl_maximum_with_max {([$($wh :tt ) *] ,$t :ty ,$max :expr ) =>{impl <$($wh ) *>MaximumBounded for $t {#[inline ] fn maximum () ->Self {$max } } } ;($t :ty ,$max :expr ) =>{impl MaximumBounded for $t {#[inline ] fn maximum () ->Self {$max } } } ;}
    impl_maximum_with_max!(usize, std::usize::MAX);
    impl_maximum_with_max!(u8, std::u8::MAX);
    impl_maximum_with_max!(u16, std::u16::MAX);
    impl_maximum_with_max!(u32, std::u32::MAX);
    impl_maximum_with_max!(u64, std::u64::MAX);
    impl_maximum_with_max!(isize, std::isize::MAX);
    impl_maximum_with_max!(i8, std::i8::MAX);
    impl_maximum_with_max!(i16, std::i16::MAX);
    impl_maximum_with_max!(i32, std::i32::MAX);
    impl_maximum_with_max!(i64, std::i64::MAX);
    macro_rules !impl_maximum_tuple {($($T :ident ) *) =>{impl <$($T :MaximumBounded ) ,*>MaximumBounded for ($($T ,) *) {#[inline ] fn maximum () ->Self {($(<$T as MaximumBounded >::maximum () ,) *) } } } ;}
    impl_maximum_tuple!();
    impl_maximum_tuple!(A);
    impl_maximum_tuple !(A B ) ;
    impl_maximum_tuple !(A B C ) ;
    impl_maximum_tuple !(A B C D ) ;
    impl_maximum_tuple !(A B C D E ) ;
    impl_maximum_tuple !(A B C D E F ) ;
    impl_maximum_tuple !(A B C D E F G ) ;
    impl_maximum_tuple !(A B C D E F G H ) ;
    impl_maximum_tuple !(A B C D E F G H I ) ;
    impl_maximum_tuple !(A B C D E F G H I J ) ;
    impl_maximum_tuple !(A B C D E F G H I J K ) ;
    impl<T: Clone + Ord + MaximumBounded> MinOperation<T> {
        pub fn new() -> Self {
            Self {
                _marker: std::marker::PhantomData,
            }
        }
    }
    impl<T: Clone + Ord + MaximumBounded> Magma for MinOperation<T> {
        type T = T;
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            std::cmp::min(x, y).clone()
        }
    }
    impl<T: Clone + Ord + MaximumBounded> Unital for MinOperation<T> {
        #[inline]
        fn unit(&self) -> Self::T {
            MaximumBounded::maximum()
        }
    }
    impl<T: Clone + Ord + MaximumBounded> Associative for MinOperation<T> {}
    impl<T: Clone + Ord + MaximumBounded> Commutative for MinOperation<T> {}
    impl<T: Clone + Ord + MaximumBounded> Idempotent for MinOperation<T> {}
}
#[derive(Clone, Debug)]
pub struct SegmentTree<M: Monoid> {
    n: usize,
    seg: Vec<M::T>,
    m: M,
}
impl<M: Monoid> SegmentTree<M> {
    pub fn new(n: usize, m: M) -> Self {
        let n = 1 << format!("{:b}", n - 1).len();
        let seg = vec![m.unit(); 2 * n];
        Self { n, seg, m }
    }
    pub fn from_vec(v: Vec<M::T>, m: M) -> Self {
        let n = 1 << format!("{:b}", v.len() - 1).len();
        let mut seg = vec![m.unit(); 2 * n];
        for (i, x) in v.into_iter().enumerate() {
            seg[n + i] = x;
        }
        for i in (1..n).rev() {
            seg[i] = m.operate(&seg[2 * i], &seg[2 * i + 1]);
        }
        Self { n, seg, m }
    }
    pub fn set(&mut self, k: usize, x: M::T) {
        debug_assert!(k < self.n);
        let mut k = k + self.n;
        self.seg[k] = x;
        k /= 2;
        while k > 0 {
            self.seg[k] = self.m.operate(&self.seg[2 * k], &self.seg[2 * k + 1]);
            k /= 2;
        }
    }
    pub fn update(&mut self, k: usize, x: M::T) {
        debug_assert!(k < self.n);
        let mut k = k + self.n;
        self.seg[k] = self.m.operate(&self.seg[k], &x);
        k /= 2;
        while k > 0 {
            self.seg[k] = self.m.operate(&self.seg[2 * k], &self.seg[2 * k + 1]);
            k /= 2;
        }
    }
    pub fn get(&self, k: usize) -> M::T {
        debug_assert!(k < self.n);
        self.seg[k + self.n].clone()
    }
    pub fn fold(&self, l: usize, r: usize) -> M::T {
        debug_assert!(l < self.n);
        debug_assert!(r <= self.n);
        let mut l = l + self.n;
        let mut r = r + self.n;
        let mut vl = self.m.unit();
        let mut vr = self.m.unit();
        while l < r {
            if l & 1 != 0 {
                vl = self.m.operate(&vl, &self.seg[l]);
                l += 1;
            }
            if r & 1 != 0 {
                r -= 1;
                vr = self.m.operate(&self.seg[r], &vr);
            }
            l /= 2;
            r /= 2;
        }
        self.m.operate(&vl, &vr)
    }
    pub fn fold_all(&self) -> M::T {
        self.seg[1].clone()
    }
    /// left most index [0, r) that satisfies monotonic condition
    pub fn lower_bound_all<F: Fn(&M::T) -> bool>(&self, f: F, r: usize) -> usize {
        if !f(&self.seg[1]) {
            return r;
        }
        let mut acc = self.m.unit();
        let mut pos = 1;
        while pos < self.n {
            pos *= 2;
            let y = self.m.operate(&acc, &self.seg[pos]);
            if !f(&y) {
                acc = y;
                pos += 1;
            }
        }
        std::cmp::min(pos - self.n, r)
    }
    /// left most index [l, r) that satisfies monotonic condition
    pub fn lower_bound<F: Fn(&M::T) -> bool>(&self, f: F, l: usize, r: usize) -> usize {
        let mut acc = self.m.unit();
        let mut pos = l + self.n;
        let mut lim = r + self.n;
        loop {
            let y = self.m.operate(&acc, &self.seg[pos]);
            if f(&y) {
                while pos < self.n {
                    pos *= 2;
                    let y = self.m.operate(&acc, &self.seg[pos]);
                    if !f(&y) {
                        acc = y;
                        pos += 1;
                    }
                }
                return std::cmp::min(pos - self.n, r);
            }
            let is_right = pos & 1 == 1;
            if pos == lim {
                return r;
            }
            pos /= 2;
            lim /= 2;
            if is_right {
                acc = y;
                pos += 1;
            }
        }
    }
}
fn main() {
    #[allow(unused_imports)]
    use std::io::{Read as _, Write as _};
    let __out = std::io::stdout();
    let mut __in_buf = String::new();
    std::io::stdin().read_to_string(&mut __in_buf).unwrap();
    let mut scanner = Scanner::new(&__in_buf);
    #[allow(unused_macros)]
    macro_rules !scan {() =>{scan !(usize ) } ;(($($t :tt ) ,*) ) =>{($(scan !($t ) ) ,*) } ;([$t :tt ;$len :expr ] ) =>{(0 ..$len ) .map (|_ |scan !($t ) ) .collect ::<Vec <_ >>() } ;({chars :$b :expr } ) =>{scanner .scan_chars_with ($b ) } ;({$t :tt =>$f :expr } ) =>{$f (scan !($t ) ) } ;(chars ) =>{scanner .scan_chars () } ;($t :ty ) =>{scanner .scan ::<$t >() } ;}
    let mut __out = std::io::BufWriter::new(__out.lock());
    #[allow(unused_macros)]
    macro_rules !print {($($arg :tt ) *) =>(::std ::write !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules !println {($($arg :tt ) *) =>(::std ::writeln !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules! echo {
        ($iter :expr ) => {
            echo!($iter, "\n")
        };
        ($iter :expr ,$sep :expr ) => {
            let mut iter = $iter.into_iter();
            if let Some(item) = iter.next() {
                print!("{}", item);
            }
            for item in iter {
                print!("{}{}", $sep, item);
            }
            println!();
        };
    }
    let n = scan!();
    let xy = scan!([(i64, i64); n]);
    let min = xy.iter().map(|&(x, y)| min!(x, y)).min().unwrap();
    let max = xy.iter().map(|&(x, y)| max!(x, y)).max().unwrap();
    let mind = xy.iter().map(|&(x, y)| min!(x, y) - min).max().unwrap();
    let maxd = xy.iter().map(|&(x, y)| max - max!(x, y)).max().unwrap();
    let mut ans = mind * maxd;
    let mut xy: Vec<_> = xy.iter().map(|&(x, y)| (min!(x, y), max!(x, y))).collect();
    xy.sort();
    let mut seg = SegmentTree::from_vec(xy.iter().map(|t| t.0).collect(), MinOperation::new());
    let mut mx = min + mind;
    chmin!(ans, (max - min) * (mx - seg.fold_all()));
    for (i, (_x, y)) in xy.into_iter().enumerate() {
        chmax!(mx, y);
        seg.set(i, y);
        chmin!(ans, (max - min) * (mx - seg.fold_all()));
    }
    println!("{}", ans);
}