module Main; import CPLib.IO; import CPLib.Monoid::Sum; import CPLib.Segtree; // import BinaryHeap; // import BoolArray; // import CPLib.Arithmetic; // import CPLib.Bipartite; // import CPLib.Bits; // import CPLib.Convolution; // import CPLib.DSegtree; // import CPLib.Graph; // import CPLib.LDSegtree; // import CPLib.LSegtree; // import CPLib.MaxFlow; // import CPLib.Memoize; // import CPLib.MinCostFlow; // import CPLib.Misc; import CPLib.Monoid; // import CPLib.String; // import CPLib.Trait; // import CPLib.TwoSat; // import CPLib.UnionFind; // import CPLib.ZP; import HashMap; // import HashSet; main : IO () = ( let n = *read_i; let as = *read_is(n); let bs = *read_is(n); if as.@(0) != bs.@(0) { println("-1") }; let as = range(1,n).fold([], |i, acm| let v = as.@(i-1).bit_xor(as.@(i)); acm.push_back(v)); let bs = range(1,n).fold([], |i, acm| let v = bs.@(i-1).bit_xor(bs.@(i)); acm.push_back(v)); if as.sort != bs.sort { println("-1") }; let n = n - 1; let mp = HashMap::empty(n); let mp = range_step(n-1, -1, -1).fold(mp, |i, mp| let a = as.@(i); // HashMapユーティリティーがほしい match mp.find(a) { none() => mp.insert(a, [i]), some(ls) => mp.insert(a, ls.push_back(i)) } ); // xs[i] = 移動後にi番目にくるべき数は最初はどこにいたか。 let (xs, _) = range(0, n).fold(([], mp), |i, (xs, mp)| let b = bs.@(i); let ls = mp.find(b).as_some; // HashMapの身代わりパターンが面倒 let mp = mp.insert(b, []); let i = ls.@(ls.@size-1); let xs = xs.push_back(i); let ls = ls.pop_back; let mp = mp.insert(b, ls); (xs, mp) ); let tree = Segtree::create(n) : Segtree (Sum I64); let (_, ans) = range(0, n).fold((tree, 0), |i, (tree, ans)| let move = xs.@(i) - i + tree.fold(xs.@(i)+1, n).@v; let ans = ans + move; let tree = tree.set(xs.@(i), Sum {v: 1}); (tree, ans) ); ans.to_string.println;; pure() );