Problem:
Score : 300 points

Problem Statement

We have two permutations P and Q of size N (that is, P and Q are both rearrangements of (1,~2,~...,~N)).

There are N! possible permutations of size N. Among them, let P and Q be the a-th and b-th lexicographically smallest permutations, respectively. Find |a - b|.

Notes

For two sequences X and Y, X is said to be lexicographically smaller than Y if and only if there exists an integer k such that X_i = Y_i~(1 \leq i < k) and X_k < Y_k.

Constraints

2 \leq N \leq 8

P and Q are permutations of size N.

Input

Input is given from Standard Input in the following format:

N
P_1 P_2 ... P_N
Q_1 Q_2 ... Q_N

Output

Print |a - b|.

Sample Input 1

3
1 3 2
3 1 2

Sample Output 1

3

There are 6 permutations of size 3: (1,~2,~3), (1,~3,~2), (2,~1,~3), (2,~3,~1), (3,~1,~2), and (3,~2,~1). Among them, (1,~3,~2) and (3,~1,~2) come 2-nd and 5-th in lexicographical order, so the answer is |2 - 5| = 3.

Sample Input 2

8
7 3 5 4 2 1 6 8
3 8 2 5 4 6 7 1

Sample Output 2

17517

Sample Input 3

3
1 2 3
1 2 3

Sample Output 3

0

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

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

namespace ConsoleApp2
{
    public class Program
    {

        static long D = (long)Math.Pow(10, 9) + 7;



        public static void Main(string[] args)
        {
            int N = int.Parse(Console.ReadLine());
            int[] Ps = Read(Console.ReadLine());
            int[] Qs = Read(Console.ReadLine());
            int P = 0;
            int Q = 0;

            int[] init = new int[N];
            for (int i = 0; i < N; i++)
            {
                init[i] = i+1;
            }

            for (int i = 0; i < N; i++)
            {
                P += (int)(Math.Pow(10, N - i - 1) * Ps[i]);
                Q += (int)(Math.Pow(10, N - i - 1) * Qs[i]);
            }

            List<int[]> all = Enumerate(init).ToList();

            int x = (all.FindIndex(i=> {
                for (int j = 0; j < N; j++)
                {
                    if (i[j] != Ps[j]) return false;
                }
                return true;
            }));
            int y = (all.FindIndex(i => {
                for (int j = 0; j < N; j++)
                {
                    if (i[j] != Qs[j]) return false;
                }
                return true;
            }));
            Console.WriteLine(Math.Max(x, y) - Math.Min(x, y));

            Console.ReadLine();
        }



        static long Com(int n, int m)
        {
            if (m == 0 || m == n) return 1;

            if (n < m) return 0;

            int[] a = new int[m];

            for (int i = 0; i < m; i++)
            {
                a[i] = n - i;
            }
            for (int i = 1; i <= m; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    if (a[j] % i == 0)
                    {
                        a[j] /= i;
                        break;
                    }
                }
            }

            long ans = 1;
            for (int i = 0; i < m; i++)
            {
                ans *= a[i];
                ans %= D;
            }
            return ans;
        }


        // 最小公倍数
        public static int Lcm(int a, int b)
        {
            return a * b / Gcd(a, b);
        }

        // ユークリッドの互除法 
        public static int Gcd(int a, int b)
        {
            if (a < b)
                // 引数を入替えて自分を呼び出す
                return Gcd(b, a);
            while (b != 0)
            {
                var remainder = a % b;
                a = b;
                b = remainder;
            }
            return a;
        }


        private static bool S(int[] data,int K ,int l ,int x)
        {
            int sum = 0;
            int max = Math.Min(x+1, data.Length);
            for (int i = l; i < max; i++)
            {
                sum += data[i];
            }
            Console.WriteLine(sum);
            return sum>=K;
        }


        public static IEnumerable<T[]> Enumerate<T>(IEnumerable<T> items)
        {
            if (items.Count() == 1)
            {
                yield return new T[] { items.First() };
                yield break;
            }
            foreach (var item in items)
            {
                var leftside = new T[] { item };
                var unused = items.Except(leftside);
                foreach (var rightside in Enumerate(unused))
                {
                    yield return leftside.Concat(rightside).ToArray();
                }
            }
        }




        private static string ReplaceOneChar(string S, int index, string newS)
        {
            string s1 = S.Substring(0, index - 1);
            string s2 = S.Substring(index);
            return s1 + newS + s2;
        }

        private static bool PartialSum(int target, int[] Ns)
        {
            //if (target == 0) return true;
            bool[][] ps = new bool[Ns.Length + 1][];

            //i=0では、どんなWに対してもfalse
            ps[0] = new bool[target+1];
            for (int i = 0; i < ps[0].Length; i++) ps[0][i] = false;

            ps[0][0] = true;


            //考慮に入れるitemを、前から順に追加していく
            for (int i = 0; i < Ns.Length; i++)
            {
                //初期化
                ps[i + 1] = new bool[target+1];

                for (int t = 0; t <= target; t++)
                {
                    if (t >= Ns[i]) ps[i + 1][t] = ps[i][t - Ns[i]] || ps[i][t];
                    else ps[i + 1][t]=ps[i][t];
                }
            }

            return ps[Ns.Length][target];
        }

        /// <summary>
        /// 引数は、W(重さ制限)、items[重さ][価値]
        /// </summary>
        /// <param name="W"></param>
        /// <param name="items"></param>
        /// <returns></returns>
        private static int DP(int W,int[][] items)
        {
            //データ
            int[][] dp = new int[items.Length+1][];

            //i=0では、どんなWに対しても0
            dp[0] = new int[W + 1];

            //考慮に入れるitemを、前から順に追加していく
            for (int i = 0; i < items.Length; i++)
            {
                //初期化
                dp[i+1] = new int[W + 1];

                for (int w = 0; w <= W; w++)
                {
                    if (w >= items[i][0]) dp[i + 1][w] = Math.Max(dp[i][w - items[i][0]]+items[i][1], dp[i][w]);
                    else dp[i + 1][w] = dp[i][w];
                }
            }
            return dp[items.Length][W];
        }

        private static int[] Read(string input)
        {
            string[] aaa = input.Split(' ');
            int num = aaa.Length;
            int[] ints = new int[num];
            for (int i = 0; i < num; i++)
            {
                ints[i] = int.Parse(aaa[i]);
            }
            
            return ints;
        }


    }


}