Problem p03670 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
typedef long long ll;
#define rep(i, a, b) for (int i = a; i <= b; ++i)
const int N = 25, M = 2e6, mo = 1e9 + 7;
using namespace std;

int n, m, T, A[N][N], g[N][M], f[2][N][M], nxt[M][N];
void upd(int &x, int y) { x = (x + y) % mo; }
int main() {
  scanf("%d%d%d", &n, &m, &T);
  if (n == 1) {
    puts("1");
    return 0;
  }
  rep(i, 0, m - 1) rep(j, 0, n - 2) A[i][j] = -1;
  for (int x, y, z; T--;) {
    scanf("%d%d%d", &x, &y, &z);
    A[x - 1][y - 1] = z;
  }
  int c = 0, st = (1 << (n - 1)) - 1;
  rep(i, 0, st) rep(j, 0, n - 2) {
    nxt[i][j] = -1;
    rep(k, j + 1, n - 2) if ((i >> k) & 1) {
      nxt[i][j] = k;
      break;
    }
  }
  g[n - 2][0] = 1;
  rep(u, 0, m - 1) {
    c ^= 1;
    rep(i, 0, n - 1) rep(j, 0, st) f[c][i][j] = 0;
    rep(i, 0, st) upd(f[c][0][i], g[n - 2][i]);
    rep(i, 0, n - 2) rep(j, 0, st) g[i][j] = 0;
    rep(i, 0, n - 2) rep(j, 0, st) {
      upd(f[c][i + 1][j], f[c][i][j]);
      if ((j >> i) & 1)
        continue;
      if (nxt[j][i] == -1)
        upd(g[i][(j & ((1 << i) - 1)) | (1 << i)], f[c][i][j]);
      else
        upd(f[c][i + 1][j ^ (1 << i) ^ (1 << nxt[j][i])], f[c][i][j]);
    }
    rep(i, 0, st) upd(g[n - 2][i], f[c][n - 1][i]);
    rep(i, 0, n - 3) rep(j, 0, st) upd(g[i + 1][j], g[i][j]),
        upd(g[i + 1][j ^ (1 << (i + 1))], g[i][j]);
    rep(i, 0, st)
        rep(j, 0, n - 2) if (A[u][j] != -1 && A[u][j] != ((i >> j) & 1))
            g[n - 2][i] = 0;
  }
  int ans = 0;
  rep(i, 0, st) upd(ans, g[n - 2][i]);
  printf("%d\n", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
typedef long long ll;
#define rep(i, a, b) for (int i = a; i <= b; ++i)
const int N = 25, M = 6e5 + 5, mo = 1e9 + 7;
using namespace std;

int n, m, T, A[N][N], g[N][M], f[2][N][M], nxt[M][N];
void upd(int &x, int y) { x = (x + y) % mo; }
int main() {
  scanf("%d%d%d", &n, &m, &T);
  if (n == 1) {
    puts("1");
    return 0;
  }
  rep(i, 0, m - 1) rep(j, 0, n - 2) A[i][j] = -1;
  for (int x, y, z; T--;) {
    scanf("%d%d%d", &x, &y, &z);
    A[x - 1][y - 1] = z;
  }
  int c = 0, st = (1 << (n - 1)) - 1;
  rep(i, 0, st) rep(j, 0, n - 2) {
    nxt[i][j] = -1;
    rep(k, j + 1, n - 2) if ((i >> k) & 1) {
      nxt[i][j] = k;
      break;
    }
  }
  g[n - 2][0] = 1;
  rep(u, 0, m - 1) {
    c ^= 1;
    rep(i, 0, n - 1) rep(j, 0, st) f[c][i][j] = 0;
    rep(i, 0, st) upd(f[c][0][i], g[n - 2][i]);
    rep(i, 0, n - 2) rep(j, 0, st) g[i][j] = 0;
    rep(i, 0, n - 2) rep(j, 0, st) {
      upd(f[c][i + 1][j], f[c][i][j]);
      if ((j >> i) & 1)
        continue;
      if (nxt[j][i] == -1)
        upd(g[i][(j & ((1 << i) - 1)) | (1 << i)], f[c][i][j]);
      else
        upd(f[c][i + 1][j ^ (1 << i) ^ (1 << nxt[j][i])], f[c][i][j]);
    }
    rep(i, 0, st) upd(g[n - 2][i], f[c][n - 1][i]);
    rep(i, 0, n - 3) rep(j, 0, st) upd(g[i + 1][j], g[i][j]),
        upd(g[i + 1][j ^ (1 << (i + 1))], g[i][j]);
    rep(i, 0, st)
        rep(j, 0, n - 2) if (A[u][j] != -1 && A[u][j] != ((i >> j) & 1))
            g[n - 2][i] = 0;
  }
  int ans = 0;
  rep(i, 0, st) upd(ans, g[n - 2][i]);
  printf("%d\n", ans);
  return 0;
}