Problem p03406 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010, M = 1000010, P = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int INF = 0xcfcfcfcf;
const double eps = 1e-6, pi = asin(1) * 2;
inline ll read();
inline void write(ll x);
inline void writeln(ll x);
#define cmax(a, b) a = max(a, b)
#define cmin(a, b) a = min(a, b)
#define plus(a, b) a = (a + (b)) % P
#define minus(a, b) a = (a - (b) + P) % P
#define mul(a, b) a = (a * (b)) % P
#define mem(a, b) memset(a, b, sizeof(a))
#define pii pair<int, int>
#define pil pair<int, ll>
#define pli pair<ll, int>
#define pll pair<ll, ll>
#define mp(x, y) make_pair(x, y)

inline ll quickmi(ll x, ll n) {
  ll res = 1;
  for (; n; n >>= 1) {
    if (n & 1)
      mul(res, x);
    mul(x, x);
  }
  return res;
}
#define ni(x) quickmi(x, P - 2)

ll fac[N], inv[N];
int num[N];
inline void init(int n = 100000) {
  fac[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = fac[i - 1] * i % P;
  inv[n] = ni(fac[n]);
  for (int i = n; i; i--)
    inv[i - 1] = inv[i] * i % P;
  num[0] = 0;
  for (int i = 1; i <= n; i++)
    num[i] = num[i >> 1] ^ (i & 1);
}
inline ll C(ll n, ll m) {
  return n >= m ? fac[n] * inv[m] % P * inv[n - m] % P : 0;
}

int n, m;
int a[N];
inline bool cmp(int x, int y) { return x > y; }
ll dp[22][(1 << 16) | 10];

#define FILE "shiratsuyu"
#ifdef FILE
char buf[1 << 25], *p1 = buf, *p2 = buf;
#define getchar()                                                              \
  p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 25, stdin), p1 == p2)      \
      ? EOF                                                                    \
      : *p1++
#endif
inline ll read() {
  ll s = 0;
  bool flag = false;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      flag = true;
  for (; '0' <= ch && ch <= '9'; ch = getchar())
    s = (s << 3) + (s << 1) + (ch ^ '0');
  if (flag)
    return -s;
  return s;
}
inline void write(ll x) {
  if (!x) {
    putchar('0'), putchar(' ');
    return;
  }
  if (x < 0)
    putchar('-'), x = -x;
  char ch[20];
  int tot = 0;
  while (x)
    ch[++tot] = x % 10, x /= 10;
  for (int i = tot; i; i--)
    putchar(ch[i] ^ 48);
  putchar(' ');
}
inline void writeln(ll x) {
  write(x);
  putchar('\n');
}

int main() {
#ifdef FILE
  freopen(FILE ".in", "r", stdin);
  freopen(FILE ".out", "w", stdout);
#endif
  init();
  n = read(), m = read();
  for (int i = 1; i <= m; i++)
    a[i] = read();
  sort(a + 1, a + m + 1, cmp);
  //	for(int i=1;i<=m;i++) cerr<<a[i]<<" ";
  //	cerr<<"\n";
  dp[0][0] = 1;
  for (int i = 1; i <= m; i++) {
    for (int S = 0; S < (1 << n); S++)
      dp[i][S] = dp[i - 1][S];
    for (int S = 0; S < (1 << n); S++) {
      for (int j = 0; j < n; j++) {
        if ((S | (1 << j)) != S)
          continue;
        int T = S - (1 << j);
        plus(dp[i][S], dp[i - 1][T] * C((1 << n) - T - a[i], (1 << j) - 1) % P *
                           fac[1 << j] % P);
      }
    }
  }

  //	for(int S=0;S<(1<<n);S++) cerr<<dp[m][S]<<" ";
  //	cerr<<"\n";

  for (int S = 0; S < (1 << n); S++)
    mul(dp[m][S], fac[(1 << n) - 1 - S]);
  ll ans = 0;
  for (int S = 0; S < (1 << n); S++)
    plus(ans, (num[S] ? -1 : 1) * dp[m][S]);
  printf("%lld\n", (ans % P + P) * (1 << n) % P);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010, M = 1000010, P = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int INF = 0xcfcfcfcf;
const double eps = 1e-6, pi = asin(1) * 2;
inline ll read();
inline void write(ll x);
inline void writeln(ll x);
#define cmax(a, b) a = max(a, b)
#define cmin(a, b) a = min(a, b)
#define plus(a, b) a = (a + (b)) % P
#define minus(a, b) a = (a - (b) + P) % P
#define mul(a, b) a = (a * (b)) % P
#define mem(a, b) memset(a, b, sizeof(a))
#define pii pair<int, int>
#define pil pair<int, ll>
#define pli pair<ll, int>
#define pll pair<ll, ll>
#define mp(x, y) make_pair(x, y)

inline ll quickmi(ll x, ll n) {
  ll res = 1;
  for (; n; n >>= 1) {
    if (n & 1)
      mul(res, x);
    mul(x, x);
  }
  return res;
}
#define ni(x) quickmi(x, P - 2)

ll fac[N], inv[N];
int num[N];
inline void init(int n = 100000) {
  fac[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = fac[i - 1] * i % P;
  inv[n] = ni(fac[n]);
  for (int i = n; i; i--)
    inv[i - 1] = inv[i] * i % P;
  num[0] = 0;
  for (int i = 1; i <= n; i++)
    num[i] = num[i >> 1] ^ (i & 1);
}
inline ll C(ll n, ll m) {
  return n >= m ? fac[n] * inv[m] % P * inv[n - m] % P : 0;
}

int n, m;
int a[N];
inline bool cmp(int x, int y) { return x > y; }
ll dp[22][(1 << 16) | 10];

// #define FILE "shiratsuyu"
#ifdef FILE
char buf[1 << 25], *p1 = buf, *p2 = buf;
#define getchar()                                                              \
  p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 25, stdin), p1 == p2)      \
      ? EOF                                                                    \
      : *p1++
#endif
inline ll read() {
  ll s = 0;
  bool flag = false;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      flag = true;
  for (; '0' <= ch && ch <= '9'; ch = getchar())
    s = (s << 3) + (s << 1) + (ch ^ '0');
  if (flag)
    return -s;
  return s;
}
inline void write(ll x) {
  if (!x) {
    putchar('0'), putchar(' ');
    return;
  }
  if (x < 0)
    putchar('-'), x = -x;
  char ch[20];
  int tot = 0;
  while (x)
    ch[++tot] = x % 10, x /= 10;
  for (int i = tot; i; i--)
    putchar(ch[i] ^ 48);
  putchar(' ');
}
inline void writeln(ll x) {
  write(x);
  putchar('\n');
}

int main() {
#ifdef FILE
  freopen(FILE ".in", "r", stdin);
  freopen(FILE ".out", "w", stdout);
#endif
  init();
  n = read(), m = read();
  for (int i = 1; i <= m; i++)
    a[i] = read();
  sort(a + 1, a + m + 1, cmp);
  //	for(int i=1;i<=m;i++) cerr<<a[i]<<" ";
  //	cerr<<"\n";
  dp[0][0] = 1;
  for (int i = 1; i <= m; i++) {
    for (int S = 0; S < (1 << n); S++)
      dp[i][S] = dp[i - 1][S];
    for (int S = 0; S < (1 << n); S++) {
      for (int j = 0; j < n; j++) {
        if ((S | (1 << j)) != S)
          continue;
        int T = S - (1 << j);
        plus(dp[i][S], dp[i - 1][T] * C((1 << n) - T - a[i], (1 << j) - 1) % P *
                           fac[1 << j] % P);
      }
    }
  }

  //	for(int S=0;S<(1<<n);S++) cerr<<dp[m][S]<<" ";
  //	cerr<<"\n";

  for (int S = 0; S < (1 << n); S++)
    mul(dp[m][S], fac[(1 << n) - 1 - S]);
  ll ans = 0;
  for (int S = 0; S < (1 << n); S++)
    plus(ans, (num[S] ? -1 : 1) * dp[m][S]);
  printf("%lld\n", (ans % P + P) * (1 << n) % P);
  return 0;
}