Problem p03052 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = (x); i <= (y); i++)
#define ll long long

using namespace std;

const int N = 25, M = (1 << 20) + 10, mod = 1e9 + 7;
int n, m, len, a[M], cnt, head[N], x, y, val[N], f[2][M], g[2][M];
struct edge {
  int to, nxt, i;
} e[N * N];

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

void adde(int x, int y, int i) {
  e[++cnt].to = y;
  e[cnt].nxt = head[x];
  head[x] = cnt;
  e[cnt].i = i;
}

void dfs(int u, int par, int st) {
  val[u] = st;
  for (int i = head[u], v; i; i = e[i].nxt)
    if (v = e[i].to, v != par)
      dfs(v, u, st | (1 << (e[i].i - 1)));
}

void fmt(int *a) {
  rep(i, 0, len - 1) rep(j, 0, (1 << len) - 1) if (!(j >> i & 1))
      a[j | 1 << i] += a[j];
}

int main() {
  scanf("%d%d", &n, &m);
  len = n - 1;
  rep(i, 1, n - 1) scanf("%d%d", &x, &y), adde(x, y, i), adde(y, x, i);
  dfs(1, 0, 0);
  rep(i, n, m) scanf("%d%d", &x, &y), a[val[x] ^ val[y]]++;
  fmt(a);
  int now = 0, tmp;
  f[0][0] = 1;
  rep(i, 1, m) {
    now ^= 1;
    memset(f[now], 0, sizeof(f[now]));
    memset(g[now], 0, sizeof(g[now]));
    rep(j, 0, (1 << len) - 1) if (tmp = f[now ^ 1][j], tmp) {
      rep(k, 0, len - 1) if (!(j >> k & 1)) {
        upd(f[now][j | (1 << k)], tmp);
        upd(g[now][j | (1 << k)], (g[now ^ 1][j] + (ll)tmp * i % mod) % mod);
      }
      upd(f[now][j], (ll)tmp * (a[j] - (i - 1 - __builtin_popcount(j))) % mod);
      upd(g[now][j],
          (ll)g[now ^ 1][j] * (a[j] - (i - 1 - __builtin_popcount(j))) % mod);
    }
  }
  printf("%d\n", g[now][(1 << len) - 1]);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = (x); i <= (y); i++)
#define ll long long

using namespace std;

const int N = 25, M = (1 << 20) + 10, mod = 1e9 + 7;
int n, m, len, a[M], cnt, head[N], x, y, val[N], f[2][M], g[2][M];
struct edge {
  int to, nxt, i;
} e[N * N];

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

void adde(int x, int y, int i) {
  e[++cnt].to = y;
  e[cnt].nxt = head[x];
  head[x] = cnt;
  e[cnt].i = i;
}

void dfs(int u, int par, int st) {
  val[u] = st;
  for (int i = head[u], v; i; i = e[i].nxt)
    if (v = e[i].to, v != par)
      dfs(v, u, st | (1 << (e[i].i - 1)));
}

void fmt(int *a) {
  rep(i, 0, len - 1) rep(j, 0, (1 << len) - 1) if (!(j >> i & 1))
      a[j | 1 << i] += a[j];
}

int main() {
  scanf("%d%d", &n, &m);
  len = n - 1;
  rep(i, 1, n - 1) scanf("%d%d", &x, &y), adde(x, y, i), adde(y, x, i);
  dfs(1, 0, 0);
  rep(i, n, m) scanf("%d%d", &x, &y), a[val[x] ^ val[y]]++;
  fmt(a);
  int now = 0, tmp;
  f[0][0] = 1;
  rep(i, 1, m) {
    now ^= 1;
    memset(f[now], 0, sizeof(f[now]));
    memset(g[now], 0, sizeof(g[now]));
    rep(j, 0, (1 << len) - 1) if (tmp = f[now ^ 1][j], tmp) {
      int s = ((1 << len) - 1) ^ j;
      for (int r = s; r; r -= r & -r) {
        int k = r & -r;
        if (!(j & k)) {
          upd(f[now][j | k], tmp);
          upd(g[now][j | k], (g[now ^ 1][j] + (ll)tmp * i % mod) % mod);
        }
      }
      upd(f[now][j], (ll)tmp * (a[j] - (i - 1 - __builtin_popcount(j))) % mod);
      upd(g[now][j],
          (ll)g[now ^ 1][j] * (a[j] - (i - 1 - __builtin_popcount(j))) % mod);
    }
  }
  printf("%d\n", g[now][(1 << len) - 1]);
  return 0;
}