Problem p03513 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

template <class T> inline void read(T &res) {
  char ch;
  while (ch = getchar(), !isdigit(ch))
    ;
  res = ch ^ 48;
  while (ch = getchar(), isdigit(ch))
    res = res * 10 + ch - 48;
}

const int N = 20;
const int M = 1005;
const int S = 1 << 15;
const int mod = 1e9 + 7;
int ex[M], f1[S], f2[S], cnt1[S], cnt2[S], g[S];
int n, m, id;
bool vis[N][N];

inline void add(int &x, int y) {
  x += y;
  x >= mod ? x -= mod : 0;
}

inline void dec(int &x, int y) {
  x -= y;
  x < 0 ? x += mod : 0;
}

int main() {
  read(n);
  read(m);
  ex[0] = 1;
  for (int i = 1, u, v; i <= m; ++i) {
    ex[i] = ex[i - 1];
    add(ex[i], ex[i - 1]);
    read(u);
    read(v);
    vis[u][v] = vis[v][u] = true;
  }
  const int C = (1 << n) - 1;
  for (int i = 1; i <= C; ++i)
    for (int j = 1; j <= n; ++j)
      if (1 << j - 1 & i)
        for (int k = j + 1; k <= n; ++k)
          if ((1 << k - 1 & i) && vis[j][k])
            ++cnt1[i];
  for (int i = 1; i <= C; ++i)
    for (int j = 1; j <= n; ++j)
      if (!(1 << j - 1 & i))
        for (int k = 1; k <= n; ++k)
          if ((1 << k - 1 & i) && vis[j][k])
            ++cnt2[i], g[i] |= 1 << j - 1;
  f1[1] = 1;
  for (int i = 2; i <= C; ++i)
    if (i & 1) {
      f1[i] = ex[cnt1[i]];
      for (int j = i - 1 & i; j; j = j - 1 & i)
        if (j & 1)
          dec(f1[i], 1ll * f1[j] * ex[cnt1[i ^ j]] % mod);
    }
  f2[2] = 1;
  for (int i = 3; i <= C; ++i)
    if (i >> 1 & 1) {
      f2[i] = ex[cnt1[i]];
      for (int j = i - 1 & i; j; j = j - 1 & i)
        if (j >> 1 & 1)
          dec(f2[i], 1ll * f2[j] * ex[cnt1[i ^ j]] % mod);
    }
  int ans = ex[m];
  for (int i = 1; i <= C; ++i)
    if (i & 1) {
      int ti = C ^ i ^ g[i];
      for (int j = ti; j; j = j - 1 & ti)
        if (j >> 1 & 1)
          dec(ans, 1ll * f1[i] * f2[j] % mod *
                       ex[m - cnt1[i] - cnt1[j] - cnt2[i] - cnt2[j]] % mod);
    }
  printf("%d\\n", ans);
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

template <class T> inline void read(T &res) {
  char ch;
  while (ch = getchar(), !isdigit(ch))
    ;
  res = ch ^ 48;
  while (ch = getchar(), isdigit(ch))
    res = res * 10 + ch - 48;
}

const int N = 20;
const int M = 1005;
const int S = 1 << 15;
const int mod = 1e9 + 7;
int ex[M], f1[S], f2[S], cnt1[S], cnt2[S], g[S];
int n, m, id;
bool vis[N][N];

inline void add(int &x, int y) {
  x += y;
  x >= mod ? x -= mod : 0;
}

inline void dec(int &x, int y) {
  x -= y;
  x < 0 ? x += mod : 0;
}

int main() {
  read(n);
  read(m);
  read(id);
  ex[0] = 1;
  for (int i = 1, u, v; i <= m; ++i) {
    ex[i] = ex[i - 1];
    add(ex[i], ex[i - 1]);
    read(u);
    read(v);
    vis[u][v] = vis[v][u] = true;
  }
  const int C = (1 << n) - 1;
  for (int i = 1; i <= C; ++i)
    for (int j = 1; j <= n; ++j)
      if (1 << j - 1 & i)
        for (int k = j + 1; k <= n; ++k)
          if ((1 << k - 1 & i) && vis[j][k])
            ++cnt1[i];
  for (int i = 1; i <= C; ++i)
    for (int j = 1; j <= n; ++j)
      if (!(1 << j - 1 & i))
        for (int k = 1; k <= n; ++k)
          if ((1 << k - 1 & i) && vis[j][k])
            ++cnt2[i], g[i] |= 1 << j - 1;
  f1[1] = 1;
  for (int i = 2; i <= C; ++i)
    if (i & 1) {
      f1[i] = ex[cnt1[i]];
      for (int j = i - 1 & i; j; j = j - 1 & i)
        if (j & 1)
          dec(f1[i], 1ll * f1[j] * ex[cnt1[i ^ j]] % mod);
    }
  f2[2] = 1;
  for (int i = 3; i <= C; ++i)
    if (i >> 1 & 1) {
      f2[i] = ex[cnt1[i]];
      for (int j = i - 1 & i; j; j = j - 1 & i)
        if (j >> 1 & 1)
          dec(f2[i], 1ll * f2[j] * ex[cnt1[i ^ j]] % mod);
    }
  int ans = ex[m];
  for (int i = 1; i <= C; ++i)
    if (i & 1) {
      int ti = C ^ i ^ g[i];
      for (int j = ti; j; j = j - 1 & ti)
        if (j >> 1 & 1)
          dec(ans, 1ll * f1[i] * f2[j] % mod *
                       ex[m - cnt1[i] - cnt1[j] - cnt2[i] - cnt2[j]] % mod);
    }
  printf("%d\\n", ans);
  return 0;
}