Problem:
Score : 500 points

Problem Statement

#nck {
width: 30px;
height: auto;
}

There are N computers and N sockets in a one-dimensional world.
The coordinate of the i-th computer is a_i, and the coordinate of the i-th socket is b_i.
It is guaranteed that these 2N coordinates are pairwise distinct.

Snuke wants to connect each computer to a socket using a cable.
Each socket can be connected to only one computer.

In how many ways can he minimize the total length of the cables?
Compute the answer modulo 10^9+7.

Constraints

1 ≤ N ≤ 10^5

0 ≤ a_i, b_i ≤ 10^9

The coordinates are integers.

The coordinates are pairwise distinct.

Input

The input is given from Standard Input in the following format:

N
a_1
:
a_N
b_1
:
b_N

Output

Print the number of ways to minimize the total length of the cables, modulo 10^9+7.

Sample Input 1

2
0
10
20
30

Sample Output 1

2

There are two optimal connections: 0-20, 10-30 and 0-30, 10-20.
In both connections the total length of the cables is 40.

Sample Input 2

3
3
10
8
7
12
5

Sample Output 2

1

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

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

namespace AtTest.CodeFestival2016Final
{
    class A
    {
        static void Main(string[] args)
        {
            Method(args);
            ReadLine();
        }

        static void Method(string[] args)
        {
            int n = ReadInt();
            var array = new int[n * 2][];
            for (int i = 0; i < n; i++)
            {
                array[i] = new int[2] { ReadInt(), 0 };
            }
            for (int i = 0; i < n; i++)
            {
                array[n + i] = new int[2] { ReadInt(), 1 };
            }
            Array.Sort(array, (a, b) => a[0] - b[0]);
            List<long> blocks = new List<long>();
            blocks.Add(1);
            for (int i = 1; i < n * 2; i++)
            {
                if (array[i - 1][1] != array[i][1])
                {
                    blocks.Add(0);
                }
                blocks[blocks.Count - 1]++;
            }
            for (int i = 0; i < blocks.Count; i++)
            {
                //WriteLine(blocks[i]);
            }

            long mask = 1000000000 + 7;
            long res = 1;
            int index = 1;
            long cnt = 0;
            for (int i = 0; i < blocks.Count; i += 2)
            {
                long remain = blocks[i];
                long before = 0;
                long after = 0;
                while (index < i && remain > 0)
                {
                    if (remain >= blocks[index] - cnt)
                    {
                        remain -= blocks[index] - cnt;
                        index += 2;
                        cnt = 0;
                    }
                    else
                    {
                        cnt = remain;
                        remain = 0;
                    }
                }
                before = blocks[i] - remain;

                while (remain > 0)
                {
                    if (remain >= blocks[index] - cnt)
                    {
                        remain -= blocks[index] - cnt;
                        index += 2;
                        cnt = 0;
                    }
                    else
                    {
                        cnt = remain;
                        remain = 0;
                    }
                }
                after = blocks[i] - before;
                res = MultiMod(res,
                    Permutation(before, before, mask), mask);
                res = MultiMod(res,
                    Permutation(after, after, mask), mask);
                if (cnt > 0 && i + 1 < index)
                {
                    res = MultiMod(res,
                        Combination(blocks[index], cnt, mask), mask);
                }
            }
            WriteLine(res);
        }

        static long Combination(long n, long m, long mask)
        {
            if (n < m) return 0;

            if (n - m < m) m = n - m;

            long val = Permutation(n, m, mask);
            long div = Permutation(m, m, mask);
            return MultiMod(val, ReverseMod(div, mask - 2, mask), mask);
        }

        static long Permutation(long n, long m, long mask)
        {
            long val = 1;
            for (long i = 0; i < m; i++)
            {
                val *= ((n - i) % mask);
                val %= mask;
            }
            return val;
        }

        static long MultiMod(long a, long b, long mask)
        {
            return ((a % mask) * (b % mask)) % mask;
        }

        static long ReverseMod(long a, long pow, long mask)
        {
            if (pow == 0) return 1;
            else if (pow == 1) return a % mask;
            else
            {
                long halfMod = ReverseMod(a, pow / 2, mask);
                long nextMod = MultiMod(halfMod, halfMod, mask);
                if (pow % 2 == 0)
                {
                    return nextMod;
                }
                else
                {
                    return MultiMod(nextMod, a, mask);
                }
            }
        }

        private static string Read() { return ReadLine(); }
        private static int ReadInt() { return int.Parse(Read()); }
        private static long ReadLong() { return long.Parse(Read()); }
        private static double ReadDouble() { return double.Parse(Read()); }
        private static int[] ReadInts() { return Array.ConvertAll(Read().Split(), int.Parse); }
        private static long[] ReadLongs() { return Array.ConvertAll(Read().Split(), long.Parse); }
        private static double[] ReadDoubles() { return Array.ConvertAll(Read().Split(), double.Parse); }
    }
}