Problem:
N: 通販 (Mail Order)

胡桃沢さんは、魔界通販で積み木のおもちゃを買った。

積み木は一辺の長さが1の立方体の形をしており、縦に $H$ 個、横に $W$ 個に分割されたマス目の上に積まれている。

真横から見ると、左から順に、$A_1, A_2, A_3, \dots, A_H$ 個のブロックが積まれて見えた。

正面から見ると、左から順に、$B_1, B_2, B_3, \dots, B_W$ 個のブロックが積まれて見えた。

胡桃沢さんは偉大なので、これらの情報だけからブロックの総数を当てようと考えた。

小さい数を答えて間違えると格好悪いので、考えられる最大の個数を答えたい。

入力

1 行目には整数 $H, W$ が空白区切りで与えられる。

2 行目には、真横から見たときの図を表す $H$ 個の整数 $A_1, A_2, A_3, \dots, A_H$ が空白区切りで与えられる。

3 行目には、正面から見たときの図を表す $W$ 個の整数 $B_1, B_2, B_3, \dots, B_W$ が空白区切りで与えられる。

出力

これらの情報から考えられるブロックの個数の最大値を出力しなさい。

制約

$H, W$ は $1$ 以上 $100 \ 000$ 以下の整数

$A_1, A_2, A_3, \dots, A_H$ は $1$ 以上 $100 \ 000 \ 000$ 以下の整数

$B_1, B_2, B_3, \dots, B_W$ は $1$ 以上 $100 \ 000 \ 000$ 以下の整数

すべての入力に対して、条件を満たすブロックの積み方があることが保証される

入力例1

2 2
1 5
1 5

出力例1

8

縦方向に $X$ 番目、横方向に $Y$ 番目のマスを $(X, Y)$ で表すことにします。

マス $(2, 2)$ に5個、マス $(1, 1)$、$(1, 2)$、$(2, 1)$ に $1$ 個ずつ積まれていると合計 $8$ 個のブロックが積まれることになります。

$9$ 個以上積まれている可能性は無いので、答えは $8$ です。

入力例2

3 3
2 4 5
3 1 5

出力例2

22

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;

namespace N
{
    class Program
    {
        static bool IsOK(int[] arr, int index, int key)
        {
            if (arr[index] >= key) return true;
            else return false;
        }

        static int Binary_search(int[] arr, int key)
        {
            int ng = -1;
            int ok = arr.Count();

            while (ok - ng > 1)
            {
                int mid = ng + (ok - ng) / 2;

                if (IsOK(arr, mid, key)) ok = mid;
                else ng = mid;
            }

            return ok;
        }
        static void Main(string[] args)
        {
            int[] x = Console.ReadLine().Split().Select(int.Parse).ToArray();
            int[] a = Console.ReadLine().Split().Select(int.Parse).ToArray();
            int[] b = Console.ReadLine().Split().Select(int.Parse).ToArray();
            Array.Sort(a); Array.Sort(b);
            long ret = 0;
            for (long i = 0; i < x[0]; i++)
            {
                ret += (x[1] - (long)Binary_search(b, a[i])) * a[i];
            }
            for (long i = 0; i < x[1]; i++)
            {
                ret += (x[0] - (long)Binary_search(a, b[i])) * b[i];
            }
            Dictionary<int, Tuple<int, int>> dic = new Dictionary<int, Tuple<int, int>>();
            for (int i = 0; i < x[0]; i++)
            {
                if (!dic.ContainsKey(a[i])) dic[a[i]] = new Tuple<int, int>(0, 0);
                dic[a[i]] = new Tuple<int, int>(dic[a[i]].Item1 + 1, dic[a[i]].Item2);
            }
            for (int i = 0; i < x[1]; i++)
            {
                if (!dic.ContainsKey(b[i])) dic[b[i]] = new Tuple<int, int>(0, 0);
                dic[b[i]] = new Tuple<int, int>(dic[b[i]].Item1, dic[b[i]].Item2 + 1);
            }
            foreach (var item in dic)
            {
                ret -= (long)item.Key * item.Value.Item1 * item.Value.Item2;
            }
            Console.WriteLine(ret);
        }
    }
}