Problem p01551 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define MOD 1000000007

int nsum;

int rest(int x, int i, int k) {
  if (k == 3) {
    return nsum - (x & 077) - (x >> 6 & 077) - (x >> 12 & 077) - i;
  }
  return (x >> (k * 6)) & 077;
}

int main() {
  int na, nt, ng, nc, m;
  cin >> na >> nt >> ng >> nc >> m;
  nsum = na + nt + ng + nc;

  cin.ignore();

  vector<string> vs(m);
  for (int i = 0; i < m; ++i) {
    getline(cin, vs[i]);
  }

  map<string, int> nametbl;
  char buf[32];
  vector<vector<char>> seq(m);
  int d = 0;

  char chtbl['T' + 1] = {};
  chtbl['A'] = 1;
  chtbl['T'] = 2;
  chtbl['G'] = 4;
  chtbl['C'] = 8;

  for (int i = m - 1; i >= 0; --i) {
    const char *ptr = vs[i].c_str();

    sscanf(ptr, "%[^:]:%n", buf, &d);
    ptr += d;
    nametbl.insert(make_pair(buf, i));

    while (*ptr != '\0') {
      if (sscanf(ptr, " %s%n", buf, &d) < 1)
        break;
      ptr += d;

      if (*buf == '[') {
        char t = 0;

        for (int j = 1; buf[j] != ']'; ++j) {
          t |= chtbl[buf[j]];
        }
        seq[i].push_back(t);
      } else {
        int j = nametbl[buf];
        seq[i].insert(seq[i].end(), seq[j].begin(), seq[j].end());
      }

      if (seq[i].size() > nsum)
        break;
    }
  }

  if (seq[0].size() > nsum) {
    throw 1;
    puts("0");
    return 0;
  }

  int last = 1 << 18;
  vector<vector<int>> dp(seq[0].size() + 1, vector<int>(last));
  dp[0][na | nt << 6 | ng << 12] = 1;

  for (int i = 0; i < seq[0].size(); ++i) {
    for (int S = 0; S < last; ++S) {
      if (dp[i][S] == 0)
        continue;

      for (int j = 0; j < 4; ++j) {
        if (!(seq[0][i] & 1 << j))
          continue;

        int c = rest(S, i, j);
        if (c > 0) {
          int t = S - ((1 << (j * 6)) & 0777777);
          dp[i + 1][t] = (dp[i + 1][t] + dp[i][S]) % MOD;
        }
      }
    }
  }

  int ans = 0;
  for (int S = 0; S < last; ++S) {
    ans = (ans + dp.back()[S]) % MOD;
  }

  printf("%d\n", ans);
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define MOD 1000000007

int nsum;

int rest(int x, int i, int k) {
  if (k == 3) {
    return nsum - (x & 077) - (x >> 6 & 077) - (x >> 12 & 077) - i;
  }
  return (x >> (k * 6)) & 077;
}

int main() {
  int na, nt, ng, nc, m;
  cin >> na >> nt >> ng >> nc >> m;
  nsum = na + nt + ng + nc;

  cin.ignore();

  vector<string> vs(m);
  for (int i = 0; i < m; ++i) {
    getline(cin, vs[i]);
  }

  map<string, int> nametbl;
  char buf[32];
  vector<vector<char>> seq(m);
  int d = 0;

  char chtbl['T' + 1] = {};
  chtbl['A'] = 1;
  chtbl['T'] = 2;
  chtbl['G'] = 4;
  chtbl['C'] = 8;

  for (int i = m - 1; i >= 0; --i) {
    const char *ptr = vs[i].c_str();

    sscanf(ptr, "%[^:]:%n", buf, &d);
    ptr += d;
    nametbl.insert(make_pair(buf, i));

    while (*ptr != '\0') {
      if (sscanf(ptr, " %s%n", buf, &d) < 1)
        break;
      ptr += d;

      if (*buf == '[') {
        char t = 0;

        for (int j = 1; buf[j] != ']'; ++j) {
          t |= chtbl[buf[j]];
        }
        seq[i].push_back(t);
      } else {
        int j = nametbl[buf];
        seq[i].insert(seq[i].end(), seq[j].begin(), seq[j].end());
      }

      if (seq[i].size() > nsum)
        break;
    }
  }

  if (seq[0].size() != nsum) {
    puts("0");
    return 0;
  }

  int last = 1 << 18;
  vector<vector<int>> dp(seq[0].size() + 1, vector<int>(last));
  dp[0][na | nt << 6 | ng << 12] = 1;

  for (int i = 0; i < seq[0].size(); ++i) {
    for (int S = 0; S < last; ++S) {
      if (dp[i][S] == 0)
        continue;

      for (int j = 0; j < 4; ++j) {
        if (!(seq[0][i] & 1 << j))
          continue;

        int c = rest(S, i, j);
        if (c > 0) {
          int t = S - ((1 << (j * 6)) & 0777777);
          dp[i + 1][t] = (dp[i + 1][t] + dp[i][S]) % MOD;
        }
      }
    }
  }

  int ans = 0;
  for (int S = 0; S < last; ++S) {
    ans = (ans + dp.back()[S]) % MOD;
  }

  printf("%d\n", ans);
}