Problem p03406 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld double

#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()

#define pb emplace_back
#define X first
#define Y second

const int N = 1 << 16;
const int mod = 1e9 + 7;

void add(int &a, int b) {
  a += b;
  if (a >= mod)
    a -= mod;
}
void sub(int &a, int b) {
  a -= b;
  if (a < 0)
    a += mod;
}
int mul(int a, int b) { return 1ll * a * b % mod; }
int inv(int a, int p) { return a == 1 ? 1 : p - 1ll * p * inv(p % a, a) / a; }
int Pow(int a, int b) {
  int ans = 1;

  while (b) {
    if (b & 1)
      ans = mul(ans, a);
    a = mul(a, a);
    b >>= 1;
  }
  return ans;
}

typedef pair<int, int> ii;
typedef pair<int, ii> pii;

int a[16];
int f[16][N];

int Fac[N];
int Inv[N];

int Ckn(int n, int k) {
  if (n < k)
    return 0;
  if (k < 0)
    return 0;

  return mul(Fac[n], mul(Inv[k], Inv[n - k]));
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  Fac[0] = Inv[0] = 1;

  for (int i = 1; i < N; ++i)
    Fac[i] = mul(Fac[i - 1], i);
  Inv[N - 1] = inv(Fac[N - 1], mod);
  for (int i = N - 2; i; --i)
    Inv[i] = mul(Inv[i + 1], i + 1);

  int n;
  cin >> n;
  int m;
  cin >> m;

  for (int i = 0; i < m; ++i)
    cin >> a[i];

  f[m][0] = 1;

  for (int i = m - 1; i >= 0; --i)
    for (int mask = 0; mask < (1 << n); ++mask) {
      f[i][mask] = f[i + 1][mask];

      for (int x = 1; x <= mask; x <<= 1)
        if (mask & x) {
          int val = f[i + 1][mask - x];

          val = mul(val, Ckn((1 << n) - a[i] - mask + x, x - 1));
          val = mul(val, Fac[x]);

          add(f[i][mask], val);
        }
    }
  int ans = 0;

  for (int mask = 0; mask < (1 << n); ++mask) {
    // cerr << f[0][mask] << " ";
    if (__builtin_popcount(mask) & 1)
      sub(ans, mul(f[0][mask], Fac[(1 << n) - mask - 1]));
    else
      add(ans, mul(f[0][mask], Fac[(1 << n) - mask - 1]));
  }
  cout << mul(ans, 1 << n) << endl;
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld double

#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()

#define pb emplace_back
#define X first
#define Y second

const int N = 1 << 16;
const int mod = 1e9 + 7;

void add(int &a, int b) {
  a += b;
  if (a >= mod)
    a -= mod;
}
void sub(int &a, int b) {
  a -= b;
  if (a < 0)
    a += mod;
}
int mul(int a, int b) { return 1ll * a * b % mod; }
int inv(int a, int p) { return a == 1 ? 1 : p - 1ll * p * inv(p % a, a) / a; }
int Pow(int a, int b) {
  int ans = 1;

  while (b) {
    if (b & 1)
      ans = mul(ans, a);
    a = mul(a, a);
    b >>= 1;
  }
  return ans;
}

typedef pair<int, int> ii;
typedef pair<int, ii> pii;

int a[17];
int f[17][N];

int Fac[N];
int Inv[N];

int Ckn(int n, int k) {
  if (n < k)
    return 0;
  if (k < 0)
    return 0;

  return mul(Fac[n], mul(Inv[k], Inv[n - k]));
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  Fac[0] = Inv[0] = 1;

  for (int i = 1; i < N; ++i)
    Fac[i] = mul(Fac[i - 1], i);
  Inv[N - 1] = inv(Fac[N - 1], mod);
  for (int i = N - 2; i; --i)
    Inv[i] = mul(Inv[i + 1], i + 1);

  int n;
  cin >> n;
  int m;
  cin >> m;

  for (int i = 0; i < m; ++i)
    cin >> a[i];

  f[m][0] = 1;

  for (int i = m - 1; i >= 0; --i)
    for (int mask = 0; mask < (1 << n); ++mask) {
      f[i][mask] = f[i + 1][mask];

      for (int x = 1; x <= mask; x <<= 1)
        if (mask & x) {
          int val = f[i + 1][mask - x];

          val = mul(val, Ckn((1 << n) - a[i] - mask + x, x - 1));
          val = mul(val, Fac[x]);

          add(f[i][mask], val);
        }
    }
  int ans = 0;

  for (int mask = 0; mask < (1 << n); ++mask) {
    // cerr << f[0][mask] << " ";
    if (__builtin_popcount(mask) & 1)
      sub(ans, mul(f[0][mask], Fac[(1 << n) - mask - 1]));
    else
      add(ans, mul(f[0][mask], Fac[(1 << n) - mask - 1]));
  }
  cout << mul(ans, 1 << n) << endl;
}