Problem:
Score : 600 points

Problem Statement

There are N points in a two-dimensional plane. The initial coordinates of the i-th point are (x_i, y_i). Now, each point starts moving at a speed of 1 per second, in a direction parallel to the x- or y- axis. You are given a character d_i that represents the specific direction in which the i-th point moves, as follows:

If d_i = R, the i-th point moves in the positive x direction;

If d_i = L, the i-th point moves in the negative x direction;

If d_i = U, the i-th point moves in the positive y direction;

If d_i = D, the i-th point moves in the negative y direction.

You can stop all the points at some moment of your choice after they start moving (including the moment they start moving).
Then, let x_{max} and x_{min} be the maximum and minimum among the x-coordinates of the N points, respectively. Similarly, let y_{max} and y_{min} be the maximum and minimum among the y-coordinates of the N points, respectively.

Find the minimum possible value of (x_{max} - x_{min}) \times (y_{max} - y_{min}) and print it.

Constraints

1 \leq N \leq 10^5

-10^8 \leq x_i,\ y_i \leq 10^8

x_i and y_i are integers.

d_i is R, L, U, or D.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1 d_1
x_2 y_2 d_2
.
.
.
x_N y_N d_N

Output

Print the minimum possible value of (x_{max} - x_{min}) \times (y_{max} - y_{min}).

The output will be considered correct when its absolute or relative error from the judge's output is at most 10^{-9}.

Sample Input 1

2
0 3 D
3 0 L

Sample Output 1

0

After three seconds, the two points will meet at the origin. The value in question will be 0 at that moment.

Sample Input 2

5
-7 -10 U
7 -6 U
-8 7 D
-3 3 D
0 -6 R

Sample Output 2

97.5

The answer may not be an integer.

Sample Input 3

20
6 -10 R
-4 -9 U
9 6 D
-3 -2 R
0 7 D
4 5 D
10 -10 U
-1 -8 U
10 -6 D
8 -5 U
6 4 D
0 3 D
7 9 R
9 -4 R
3 10 D
1 9 U
1 -6 U
9 -8 R
6 7 D
7 -3 D

Sample Output 3

273

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

/*------------------------------------------------------------------*/
/*------------------------- begin template -------------------------*/
/*------------------------------------------------------------------*/

// ref: tanakh <https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8>
// diff: using Parser
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut parser = Parser::from_str($s);
        input_inner!{parser, $($r)*}
    };
    (parser = $parser:ident, $($r:tt)*) => {
        input_inner!{$parser, $($r)*}
    };
    (new_stdin_parser = $parser:ident, $($r:tt)*) => {
        let stdin = std::io::stdin();
        let reader = std::io::BufReader::new(stdin.lock());
        let mut $parser = Parser::new(reader);
        input_inner!{$parser, $($r)*}
    };
    ($($r:tt)*) => {
        input!{new_stdin_parser = parser, $($r)*}
    };
}

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

macro_rules! read_value {
    ($parser:ident, ( $($t:tt),* )) => {
        ( $(read_value!($parser, $t)),* )
    };
    ($parser:ident, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($parser, $t)).collect::<Vec<_>>()
    };
    ($parser:ident, chars) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()
    };
    ($parser:ident, char_) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()[0]
    };
    ($parser:ident, usize1) => {
        read_value!($parser, usize) - 1
    };
    ($parser:ident, i64_) => {
        $parser.fast_i64()
    };
    ($parser:ident, usize_) => {
        $parser.fast_i64() as usize
    };
    ($parser:ident, usize1_) => {
        ($parser.fast_i64() - 1) as usize
    };
    ($parser:ident, $t:ty) => {
        $parser.next::<$t>().expect("Parse error")
    };
}

use std::io;
use std::io::BufRead;
use std::str;

// ref: tatsuya6502 <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e>
// ref: wariuni <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e#comment-7040a5ae96305e884eb9>
// diff: using std::io::BufRead::fill_buf()
pub struct Parser<R> {
    pub reader: R,
    buf: Vec<u8>,
    pos: usize,
}

impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}

impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return unsafe { str::from_utf8_unchecked(&self.buf[begin..end]) }.parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
    pub fn fast_i64(&mut self) -> i64 {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            if begin == self.buf.len() {
                self.update_buf();
                continue;
            }
            let mut res = 0;
            let (is_positive, mut end) = match self.buf[begin] {
                b'+' => (true, begin + 1),
                b'-' => (false, begin + 1),
                _ => (true, begin),
            };
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                res = res * 10 + (self.buf[end] as i64 - '0' as i64);
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return if is_positive { res } else { -res };
            } else {
                self.update_buf();
            }
        }
    }
}

#[allow(unused_imports)]
use std::cmp::*;

fn main() {
    input! {
        new_stdin_parser = parser,
    }
    let res = solve(&mut parser);
    print!("{}", res);
}

/*------------------------------------------------------------------*/
/*-------------------------- end template --------------------------*/
/*------------------------------------------------------------------*/

use std::fmt::Write;
fn solve<R: BufRead>(parser: &mut Parser<R>) -> String {
    let mut buf = String::new();
    input! {
        parser = parser,
        n: usize,
        xs: [(i64,i64,char_); n],
    }
    let inf = 1i64 << 60;
    let r_x_min = xs
        .iter()
        .filter(|&&x| x.2 == 'R')
        .map(|&x| x.0 * 2)
        .min()
        .unwrap_or(inf);
    let r_x_max = xs
        .iter()
        .filter(|&&x| x.2 == 'R')
        .map(|&x| x.0 * 2)
        .max()
        .unwrap_or(-inf);
    let r_y_min = xs
        .iter()
        .filter(|&&x| x.2 == 'R')
        .map(|&x| x.1 * 2)
        .min()
        .unwrap_or(inf);
    let r_y_max = xs
        .iter()
        .filter(|&&x| x.2 == 'R')
        .map(|&x| x.1 * 2)
        .max()
        .unwrap_or(-inf);
    let l_x_min = xs
        .iter()
        .filter(|&&x| x.2 == 'L')
        .map(|&x| x.0 * 2)
        .min()
        .unwrap_or(inf);
    let l_x_max = xs
        .iter()
        .filter(|&&x| x.2 == 'L')
        .map(|&x| x.0 * 2)
        .max()
        .unwrap_or(-inf);
    let l_y_min = xs
        .iter()
        .filter(|&&x| x.2 == 'L')
        .map(|&x| x.1 * 2)
        .min()
        .unwrap_or(inf);
    let l_y_max = xs
        .iter()
        .filter(|&&x| x.2 == 'L')
        .map(|&x| x.1 * 2)
        .max()
        .unwrap_or(-inf);
    let u_x_min = xs
        .iter()
        .filter(|&&x| x.2 == 'U')
        .map(|&x| x.0 * 2)
        .min()
        .unwrap_or(inf);
    let u_x_max = xs
        .iter()
        .filter(|&&x| x.2 == 'U')
        .map(|&x| x.0 * 2)
        .max()
        .unwrap_or(-inf);
    let u_y_min = xs
        .iter()
        .filter(|&&x| x.2 == 'U')
        .map(|&x| x.1 * 2)
        .min()
        .unwrap_or(inf);
    let u_y_max = xs
        .iter()
        .filter(|&&x| x.2 == 'U')
        .map(|&x| x.1 * 2)
        .max()
        .unwrap_or(-inf);
    let d_x_min = xs
        .iter()
        .filter(|&&x| x.2 == 'D')
        .map(|&x| x.0 * 2)
        .min()
        .unwrap_or(inf);
    let d_x_max = xs
        .iter()
        .filter(|&&x| x.2 == 'D')
        .map(|&x| x.0 * 2)
        .max()
        .unwrap_or(-inf);
    let d_y_min = xs
        .iter()
        .filter(|&&x| x.2 == 'D')
        .map(|&x| x.1 * 2)
        .min()
        .unwrap_or(inf);
    let d_y_max = xs
        .iter()
        .filter(|&&x| x.2 == 'D')
        .map(|&x| x.1 * 2)
        .max()
        .unwrap_or(-inf);
    let mut res = inf as f64;
    for t in 0..4_0000_0000 {
        let min_x = min(min(min(r_x_min + t, l_x_min - t), u_x_min), d_x_min);
        let max_x = max(max(max(r_x_max + t, l_x_max - t), u_x_max), d_x_max);
        let min_y = min(min(min(u_y_min + t, d_y_min - t), r_y_min), l_y_min);
        let max_y = max(max(max(u_y_max + t, d_y_max - t), r_y_max), l_y_max);
        let t = (max_x - min_x) * (max_y - min_y);
        if res > t as f64 / 4.0 {
            res = t as f64 / 4.0;
        }
    }
    writeln!(buf, "{}", res);
    buf
}