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 JavaScript (node.js v5.12) (judge verdict: Accepted)

"use strict";
function Main(input) {
	let textNum = input.split('\n')[0]*1;
  	
  	// 両方とも後で配列の値を比較するために文字列化
  	let text1 = input.split('\n')[1].split(' ').map(i => i*1).toString();
    let text2 = input.split('\n')[2].split(' ').map(i => i*1).toString();
  	  	
  	// 1からの連番配列を生成 
	const dictionaryResorce = [...Array(textNum).keys()].map(i => ++i);
  
  	// 配列を比較したかったのでmapで各要素を文字列にしてる
  	const dictionary = makeOrder(dictionaryResorce).map(x => x.toString());
  	
  	// それぞれが何番目かを計算
  	const x1 = dictionary.indexOf(text1);
    const x2 = dictionary.indexOf(text2);
  
  	// 答えを出す
	let ans = Math.abs(x1 - x2); 
  	console.log(ans);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));

//辞書網羅用のコード （https://gist.github.com/umezo/8582650）
function makeOrder( list ){
  //要素がなければ並び順は作れない
  if( list.length === 0 ){
    return null;
  }
  //再帰にありがちな固定return
  if( list.length === 1 ){
    return [ [ list[0] ] ];
  }
  let //生成された並び順を格納する配列
      result = [], 

      //一時変数 ループ中の先頭要素
      head,

      //一時変数 ループ内で破壊的にlistを弄りたいため
      cloneList;
  for( var i = 0 , n = list.length; i<n ; i++ ){

    //listをクローン
    cloneList = list.concat([]);

    //準々に先頭要素を交代していく
    head = cloneList.splice( i,1 );

    //先頭要素以外で全ての並び順を生成する (再帰)
    let remainList = makeOrder( cloneList );

    //生成されたルートに先頭要素を足す
    for( var j = 0 , m = remainList.length ; j<m ; j++ ){
      remainList[j].unshift( head[0] );
      result.push( remainList[j] );
    }   
  }

  return result;
}