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.Collections.Generic;
using System.Linq;
using static Input;
using static Prog;
using NX = System.Int64;

public class Solver
{
    public void Solve()
    {
        int N = NextInt();
        NextPermutation NP = new NextPermutation();
        var np = NP.Run(N);
        int[] P = LineInt().Select(v => v - 1).ToArray();
        int[] Q = LineInt().Select(v => v - 1).ToArray();
        int count = 0, p = 0, q = 0;
        foreach (var e in np)
        {
            bool p_ok = true;
            bool q_ok = true;
            for (int i = 0; i < N; i++)
            {
                if (e[i] != P[i]) p_ok = false;
                if (e[i] != Q[i]) q_ok = false;
            }
            if (p_ok) p = count;
            if (q_ok) q = count;
            count++;
        }
        Console.WriteLine(Math.Abs(p-q));
    }
}

public class NextPermutation
{
    public List<List<int>> ret;
    private Queue<List<int>> Q;

    public NextPermutation()
    {
        ret = new List<List<int>>();
        Q = new Queue<List<int>>();
    }

    public List<List<int>> Run(int N)
    {
        for (int i = 0; i < N; i++)
        {
            List<int> box = new List<int>();
            box.Add(i);
            Q.Enqueue(box);
        }
        while (Q.Count() != 0)
        {
            List<int> box = Q.Dequeue();
            if (box.Count() == N) { ret.Add(box); }
            else
            {
                for (int i = 0; i < N; i++)
                {
                    if (!box.Contains(i))
                    {
                        List<int> b = new List<int>(box);
                        b.Add(i);
                        Q.Enqueue(b);
                    }
                }
            }
        }
        return ret;
    }
}

public class Prog
{
    public const long MOD = 1000000007;
    public const int INF = 1000000007;
    public struct Pair { public int x, y; public Pair(int a, int b) { x = a; y = b; } }
    static void Main()
    {
        var sw = new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        new Solver().Solve();
        Console.Out.Flush();
        return;
    }
}

public class Input
{
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
    public long Abs(long a, long b) => Math.Abs(a - b);
}