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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
using static System.Console;
using System.Text;

namespace AtCoder_Beginner_Contest_130
{
    class Program
    {
        static public long[] Sarray() { return ReadLine().Split().Select(long.Parse).ToArray(); }
        static public List<long> Slist() { return ReadLine().Split().Select(long.Parse).ToList(); }

        static readonly public int DMV = 0;        //動かないやつ
        static readonly public int PLUS = 1;       //右or上に動くやつ
        static readonly public int MINUS = 2;      //左or下に動くやつ

        static void Main(string[] args)
        {
            var N = Sarray()[0];

            var xmax = new long[3];
            var xmin = new long[3];
            var ymax = new long[3];
            var ymin = new long[3];
            for(var i=0;i<3;++i)
            {
                xmax[i] = long.MinValue;
                ymax[i] = long.MinValue;
                xmin[i] = long.MaxValue;
                ymin[i] = long.MaxValue;
            }
            var xex = new bool[3];
            var yex = new bool[3];
            //それぞれの最大値と最小値を調べる
            for (var i = 0; i < N; ++i)
            {
                var xyd = ReadLine().Split();
                if (xyd[2] == "L" || xyd[2] == "R")//y:動かない
                {
                    if (xyd[2] == "L")//x:左
                    {
                        xmax[MINUS] = Math.Max(xmax[MINUS], int.Parse(xyd[0]));
                        xmin[MINUS] = Math.Min(xmin[MINUS], int.Parse(xyd[0]));
                        xex[MINUS] = true;
                    }
                    else//x:右
                    {
                        xmax[PLUS] = Math.Max(xmax[PLUS], int.Parse(xyd[0]));
                        xmin[PLUS] = Math.Min(xmin[PLUS], int.Parse(xyd[0]));
                        xex[PLUS] = true;
                    }
                    ymax[DMV] = Math.Max(ymax[DMV], int.Parse(xyd[1]));
                    ymin[DMV] = Math.Min(ymin[DMV], int.Parse(xyd[1]));
                    yex[DMV] = true;
                }
                else//x:動かない
                {
                    if (xyd[2] == "D")//y:下
                    {
                        ymax[MINUS] = Math.Max(ymax[MINUS], int.Parse(xyd[1]));
                        ymin[MINUS] = Math.Min(ymin[MINUS], int.Parse(xyd[1]));
                        yex[MINUS] = true;
                    }
                    else//y:上
                    {
                        ymax[PLUS] = Math.Max(ymax[PLUS], int.Parse(xyd[1]));
                        ymin[PLUS] = Math.Min(ymin[PLUS], int.Parse(xyd[1]));
                        yex[PLUS] = true;
                    }
                    xmax[DMV] = Math.Max(xmax[DMV], int.Parse(xyd[0]));
                    xmin[DMV] = Math.Min(xmin[DMV], int.Parse(xyd[0]));
                    xex[DMV] = true;
                }
            }
            //傾きが変わる時間を出す
            var t = new List<double>();
            t.Add(0);
            //差分をとってやって正となったものだけ使えば良い
            if (xex[DMV] && xex[PLUS])
            {
                t.Add(xmax[DMV] - xmax[PLUS]);
                t.Add(xmax[DMV] - xmin[PLUS]);
                t.Add(xmin[DMV] - xmax[PLUS]);
                t.Add(xmin[DMV] - xmin[PLUS]);
            }
            if (xex[DMV] && xex[MINUS])
            {
                t.Add(xmax[MINUS] - xmax[DMV]);
                t.Add(xmin[MINUS] - xmax[DMV]);
                t.Add(xmax[MINUS] - xmin[DMV]);
                t.Add(xmin[MINUS] - xmin[DMV]);
            }
            //めんどうなので両方入れたれ
            if (xex[MINUS] && xex[PLUS])
            {
                t.Add((double)(xmax[MINUS] - xmax[PLUS]) / 2);
                t.Add((double)(xmin[MINUS] - xmax[PLUS]) / 2);
                t.Add((double)(xmax[MINUS] - xmin[PLUS]) / 2);
                t.Add((double)(xmin[MINUS] - xmin[PLUS]) / 2);
            }
            if (yex[DMV] && yex[PLUS])
            {
                t.Add(ymax[DMV] - ymax[PLUS]);
                t.Add(ymax[DMV] - ymin[PLUS]);
                t.Add(ymin[DMV] - ymax[PLUS]);
                t.Add(ymin[DMV] - ymin[PLUS]);
            }
            if (yex[DMV] && yex[MINUS])
            {
                t.Add(ymax[MINUS] - ymax[DMV]);
                t.Add(ymin[MINUS] - ymax[DMV]);
                t.Add(ymax[MINUS] - ymin[DMV]);
                t.Add(ymin[MINUS] - ymin[DMV]);
            }
            if (yex[PLUS] && yex[MINUS])
            {
                t.Add((double)(ymax[MINUS] - ymax[PLUS]) / 2);
                t.Add((double)(ymin[MINUS] - ymax[PLUS]) / 2);
                t.Add((double)(ymax[MINUS] - ymin[PLUS]) / 2);
                t.Add((double)(ymin[MINUS] - ymin[PLUS]) / 2);
            }
            //それぞれの時間でそれぞれの最大値を出して計算する
            var minarea = double.MaxValue;
            foreach(var tm in t)
            {
                if (tm < 0) continue;

                var Xmax = double.MinValue;
                var Xmin = double.MaxValue;
                if (xex[DMV])
                {
                    Xmax = Math.Max(Xmax, xmax[DMV]);
                    Xmin = Math.Min(Xmin, xmin[DMV]);
                }
                if (xex[PLUS])
                {
                    Xmax = Math.Max(Xmax, xmax[PLUS] + tm);
                    Xmin = Math.Min(Xmin, xmin[PLUS] + tm);
                }
                if (xex[MINUS])
                {
                    Xmax = Math.Max(Xmax, xmax[MINUS] - tm);
                    Xmin = Math.Min(Xmin, xmin[MINUS] - tm);
                }
                var Ymax = double.MinValue;
                var Ymin = double.MaxValue;
                if (yex[DMV])
                {
                    Ymax = Math.Max(Ymax, ymax[DMV]);
                    Ymin = Math.Min(Ymin, ymin[DMV]);
                }
                if (yex[PLUS])
                {
                    Ymax = Math.Max(Ymax, ymax[PLUS] + tm);
                    Ymin = Math.Min(Ymin, ymin[PLUS] + tm);
                }
                if (yex[MINUS])
                {
                    Ymax = Math.Max(Ymax, ymax[MINUS] - tm);
                    Ymin = Math.Min(Ymin, ymin[MINUS] - tm);
                }
                minarea = Math.Min(minarea, (Xmax - Xmin) * (Ymax - Ymin));
            }
            WriteLine(minarea);
        }
    }
}