Problem p01405 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

const int MOD = 1e9 + 7;

string str1[600];
string str2[600];
vector<int> g1[600], g2[600];
bool goal1[600], goal2[600];
int A[600], B[600];
int n1, m1;
int n2, m2;

int memo[600][6][600];

int solve(int p1, int q1, int p2, int q2) {
  // cout << p1 << " " << q1 << " " << p2 << " " <<  q2 << endl;
  if (q2 == 0 && memo[p1][q1][p2] >= 0)
    return memo[p1][q1][p2];
  if (!goal1[p1] && q1 == str1[p1].size()) {
    ll res = 0;
    FOR(it, g1[p1])
    res = (res + solve(*it, 0, p2, q2)) % MOD;
    if (q2 == 0)
      memo[p1][q1][p2] = res;
    return res;
  }
  if (!goal2[p2] && q2 == str2[p2].size()) {
    ll res = 0;
    FOR(it, g2[p2])
    res = (res + solve(p1, q1, *it, 0)) % MOD;
    return res;
  }
  bool f1 = (goal1[p1] && q1 == str1[p1].size());
  bool f2 = (goal2[p2] && q2 == str2[p2].size());
  int res;
  if (f1 || f2) {
    res = f1 && f2;
  } else {
    if (str1[p1][q1] == str2[p2][q2]) {
      res = solve(p1, q1 + 1, p2, q2 + 1);
    } else {
      res = 0;
    }
  }
  if (q2 == 0)
    memo[p1][q1][p2] = res;
  return res;
}

int main() {
  int T;
  cin >> T;
  while (T--) {
    cin >> n1 >> m1;
    REP(i, m1) g1[i].clear();
    memset(goal1, 0, sizeof(goal1));
    vector<int> start1;
    REP(i, m1) {
      cin >> A[i] >> B[i] >> str1[i];
      if (A[i] == 0)
        start1.push_back(i);
      if (B[i] == n1 - 1)
        goal1[i] = 1;
      REP(j, i) {
        if (B[j] == A[i]) {
          g1[j].push_back(i);
        }
      }
    }
    cin >> n2 >> m2;
    REP(i, m2) g2[i].clear();
    memset(goal2, 0, sizeof(goal2));
    vector<int> start2;
    REP(i, m2) {
      cin >> A[i] >> B[i] >> str2[i];
      if (A[i] == 0)
        start2.push_back(i);
      if (B[i] == n2 - 1)
        goal2[i] = 1;
      REP(j, i) {
        if (B[j] == A[i]) {
          g2[j].push_back(i);
        }
      }
    }
    ll res = 0;
    memset(memo, -1, sizeof(memo));
    FOR(it, start1) {
      FOR(jt, start2) { res = (res + solve(*it, 0, *jt, 0)) % MOD; }
    }
    cout << res << endl;
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

const int MOD = 1e9 + 7;

string str1[600];
string str2[600];
vector<int> g1[600], g2[600];
bool goal1[600], goal2[600];
int A[600], B[600];
int n1, m1;
int n2, m2;

int memo[600][5][30][5];

int solve(int p1, int q1, int p2, int q2) {
  // cout << p1 << " " << q1 << " " << p2 << " " <<  q2 << endl;
  if (p2 < 30 && memo[p1][q1][p2][q2] >= 0)
    return memo[p1][q1][p2][q2];
  if (!goal1[p1] && q1 == str1[p1].size()) {
    ll res = 0;
    FOR(it, g1[p1])
    res = (res + solve(*it, 0, p2, q2)) % MOD;
    return memo[p1][q1][p2][q2] = res;
  }
  if (!goal2[p2] && q2 == str2[p2].size()) {
    ll res = 0;
    FOR(it, g2[p2])
    res = (res + solve(p1, q1, *it, 0)) % MOD;
    return memo[p1][q1][p2][q2] = res;
  }
  bool f1 = (goal1[p1] && q1 == str1[p1].size());
  bool f2 = (goal2[p2] && q2 == str2[p2].size());
  if (f1 || f2)
    return memo[p1][q1][p2][q2] = f1 && f2;
  if (str1[p1][q1] == str2[p2][q2]) {
    return memo[p1][q1][p2][q2] = solve(p1, q1 + 1, p2, q2 + 1);
  } else {
    return memo[p1][q1][p2][q2] = 0;
  }
}

int main() {
  int T;
  cin >> T;
  while (T--) {
    cin >> n1 >> m1;
    REP(i, m1) g1[i].clear();
    memset(goal1, 0, sizeof(goal1));
    vector<int> start1;
    REP(i, m1) {
      cin >> A[i] >> B[i] >> str1[i];
      if (A[i] == 0)
        start1.push_back(i);
      if (B[i] == n1 - 1)
        goal1[i] = 1;
      REP(j, i) {
        if (B[j] == A[i]) {
          g1[j].push_back(i);
        }
      }
    }
    cin >> n2 >> m2;
    REP(i, m2) g2[i].clear();
    memset(goal2, 0, sizeof(goal2));
    vector<int> start2;
    REP(i, m2) {
      cin >> A[i] >> B[i] >> str2[i];
      if (A[i] == 0)
        start2.push_back(i);
      if (B[i] == n2 - 1)
        goal2[i] = 1;
      REP(j, i) {
        if (B[j] == A[i]) {
          g2[j].push_back(i);
        }
      }
    }
    ll res = 0;
    memset(memo, -1, sizeof(memo));
    FOR(it, start1) {
      FOR(jt, start2) { res = (res + solve(*it, 0, *jt, 0)) % MOD; }
    }
    cout << res << endl;
  }
}