// Evgeny Kapun, Dec 11 2016 import java.util.Arrays; public class A007767 { static int n; static int popcnt[], noto[]; static int cans[], nans[], perm[]; static long ans[]; static long solve(int pos, int mask) { if (pos == n) { // res can't exceed n!. On the last iteration (when n==maxN), it may exceed the range of int, but then nans==null. long res = 0; int min = n; for (int i = 0; i < n; i++) { if (perm[i] > min) { continue; } int key = 0; for (int j = 0, jj = 0, mul = 1, cmask = 0; j < n; j++) { if (j == i) { continue; } int p = perm[j]; key += popcnt[cmask & ((1 << p) - 1)] * mul; mul *= ++jj; cmask |= 1 << p; } res += cans[key]; min = perm[i]; } int key = 0; for (int j = 0, mul = 1, cmask = 0; j < n;) { int p = perm[j]; key += popcnt[cmask & ((1 << p) - 1)] * mul; mul *= ++j; cmask |= 1 << p; } if (nans != null) { if (res != (int) res) { throw new AssertionError(); } nans[key] = (int) res; } return res; } long res = 0; for (int cmask = mask, i = noto[mask]; i < n; cmask |= 1 << i, i = noto[cmask]) { perm[pos] = i; res += solve(pos + 1, mask | (1 << i)); } return res; } public static void main(String[] args) { int maxN = 13; // (maxN-1)! and (1<