Problem p01551 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <string>
#include <vector>
//    #include <boost/multiprecision/cpp_int.hpp>
#include <functional>
//    #define int long long
#define inf 1000000007
#define pa pair<int, int>
#define ll long long
#define pal pair<double, int>
#define ppa pair<pa, int>
#define ppap pair<int, pa>
#define ssa pair<string, int>
#define mp make_pair
#define pb push_back
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)

using namespace std;
// priority_queue<int, vector<int>, greater<int> > que;
class Point {
public:
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}
  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double a) { return Point(x * a, y * a); }
  Point operator/(double a) { return Point(x / a, y / a); }
  double absv() { return sqrt(norm()); }
  double norm() { return x * x + y * y; }
  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};
typedef Point Vector;

struct Segment {
  Point p1, p2;
};

double hen(Vector a) {
  if (fabs(a.x) < EPS && a.y > 0)
    return acos(0);
  else if (fabs(a.x) < EPS && a.y < 0)
    return 3 * acos(0);
  else if (fabs(a.y) < EPS && a.x < 0)
    return 2 * acos(0);
  else if (fabs(a.y) < EPS && a.x > 0)
    return 0.0;
  else if (a.y > 0)
    return acos(a.x / a.absv());
  else
    return 2 * acos(0) + acos(-a.x / a.absv());
}

string itos(int i) {
  ostringstream s;
  s << i;
  return s.str();
}

int gcd(int v, int b) {
  if (v > b)
    return gcd(b, v);
  if (v == b)
    return b;
  if (b % v == 0)
    return v;
  return gcd(v, b % v);
}
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }

double distans(double x1, double y1, double x2, double y2) {
  double rr = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
  return sqrt(rr);
}
/*}
int pr[100010];
//int inv[100010];

int beki(int wa,int rr){
if(rr==0) return 1ll;
if(rr==1) return wa;
if(rr%2==1) return (beki(wa,rr-1)*wa)%inf;
int zx=beki(wa,rr/2);
return (zx*zx)%inf;
}

void gya(){
pr[0]=1;
for(int i=1;i<100010;i++){
pr[i]=(pr[i-1]*i)%inf;
}
for(int i=0;i<100010;i++) inv[i]=beki(pr[i],inf-2);

}

*/

//----------------kokomade tenpure------------
int na, nt, ng, nc, m;
string s[200];
map<string, vector<int>> ma;

int dp[210][51][51][51] = {0};

int ch(string s) {
  //	cout<<s<<endl;
  int l = s.length();
  int cv[4] = {0};

  for (int i = 0; i < l; i++) {
    if (s[i] == 'A')
      cv[0] = 1;
    if (s[i] == 'T')
      cv[1] = 1;
    if (s[i] == 'C')
      cv[2] = 1;
    if (s[i] == 'G')
      cv[3] = 1;
  }
  return cv[0] * 8 + cv[1] * 4 + cv[2] * 2 + cv[3];
}

string t, t2;
vector<int> as;
signed main() {
  cin >> na >> nt >> ng >> nc >> m;
  getline(cin, s[0]);
  for (int i = 1; i <= m; i++) {
    getline(cin, s[i]);
    s[i] += " ";
  }

  //	s[m] +=" ";

  for (int i = m; i >= 1; i--) {
    as.clear();

    vector<int> z;
    for (int j = 0; j < s[i].length() - 1; j++)
      if (s[i][j] == ' ')
        z.pb(j);
    z.pb(s[i].length() - 1);

    t = s[i].substr(0, z[0] - 1);
    //	cout<<"t "<<t<<endl;
    for (int j = 1; j < z.size(); j++) {

      t2 = s[i].substr(z[j - 1] + 1, z[j] - z[j - 1] - 1);
      //		cout<<"t2 "<<t2<<endl;
      if (t2[0] == '[' && t2[t2.length() - 1] == ']') {

        as.pb(ch(t2));
      } else {
        //		cout<<"sss"<<ma["a"].size()<<endl;
        vector<int> y = ma[t2];

        for (int ii = 0; ii < y.size(); ii++) {
          as.pb(y[ii]);
        }
      }

      //	cout<<"assize "<<as.size()<<endl;
    }
    //		cout<<t<<" "<<as.size()<<endl;
    ma[t] = as;
  }
  //	cout<<as.size()<<endl;
  if (as.size() != na + nt + nc + ng) {
    cout << 0 << endl;
    return 0;
  }

  dp[0][0][0][0] = 1;

  int r[4] = {0};
  for (int i = 0; i < as.size(); i++) {
    if (as[i] % 2 == 0)
      r[3] = 0;
    else
      r[3] = 1;
    as[i] /= 2;
    if (as[i] % 2 == 0)
      r[2] = 0;
    else
      r[2] = 1;
    as[i] /= 2;
    if (as[i] % 2 == 0)
      r[1] = 0;
    else
      r[1] = 1;
    as[i] /= 2;
    if (as[i] % 2 == 0)
      r[0] = 0;
    else
      r[0] = 1;
    //		for(int j=0;j<4;j++) cout<<r[j]<<" ";
    //		cout<<endl;

    for (int aa = 0; aa <= 50; aa++)
      for (int tt = 0; tt <= 50; tt++)
        for (int cc = 0; cc <= 50; cc++) {
          if (dp[i][aa][tt][cc] == 0)
            continue;
          for (int j = 0; j < 4; j++) {
            if (r[j] == 0)
              continue;
            if (j == 0 && aa + 1 <= 50) {
              dp[i + 1][aa + 1][tt][cc] += dp[i][aa][tt][cc];
              dp[i + 1][aa + 1][tt][cc] %= inf;
            }
            if (j == 1 && tt + 1 <= 50) {
              dp[i + 1][aa][tt + 1][cc] += dp[i][aa][tt][cc];
              dp[i + 1][aa][tt + 1][cc] %= inf;
            }
            if (j == 2 && cc + 1 <= 50) {
              dp[i + 1][aa][tt][cc + 1] += dp[i][aa][tt][cc];
              dp[i + 1][aa][tt][cc + 1] %= inf;
            }
            if (j == 3) {
              dp[i + 1][aa][tt][cc] += dp[i][aa][tt][cc];
              dp[i + 1][aa][tt][cc] %= inf;
            }
          }
        }
  }

  cout << dp[as.size()][na][nt][nc] << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <string>
#include <vector>
//    #include <boost/multiprecision/cpp_int.hpp>
#include <functional>
//    #define int long long
#define inf 1000000007
#define pa pair<int, int>
#define ll long long
#define pal pair<double, int>
#define ppa pair<pa, int>
#define ppap pair<int, pa>
#define ssa pair<string, int>
#define mp make_pair
#define pb push_back
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)

using namespace std;
// priority_queue<int, vector<int>, greater<int> > que;
class Point {
public:
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}
  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double a) { return Point(x * a, y * a); }
  Point operator/(double a) { return Point(x / a, y / a); }
  double absv() { return sqrt(norm()); }
  double norm() { return x * x + y * y; }
  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};
typedef Point Vector;

struct Segment {
  Point p1, p2;
};

double hen(Vector a) {
  if (fabs(a.x) < EPS && a.y > 0)
    return acos(0);
  else if (fabs(a.x) < EPS && a.y < 0)
    return 3 * acos(0);
  else if (fabs(a.y) < EPS && a.x < 0)
    return 2 * acos(0);
  else if (fabs(a.y) < EPS && a.x > 0)
    return 0.0;
  else if (a.y > 0)
    return acos(a.x / a.absv());
  else
    return 2 * acos(0) + acos(-a.x / a.absv());
}

string itos(int i) {
  ostringstream s;
  s << i;
  return s.str();
}

int gcd(int v, int b) {
  if (v > b)
    return gcd(b, v);
  if (v == b)
    return b;
  if (b % v == 0)
    return v;
  return gcd(v, b % v);
}
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }

double distans(double x1, double y1, double x2, double y2) {
  double rr = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
  return sqrt(rr);
}
/*}
int pr[100010];
//int inv[100010];

int beki(int wa,int rr){
if(rr==0) return 1ll;
if(rr==1) return wa;
if(rr%2==1) return (beki(wa,rr-1)*wa)%inf;
int zx=beki(wa,rr/2);
return (zx*zx)%inf;
}

void gya(){
pr[0]=1;
for(int i=1;i<100010;i++){
pr[i]=(pr[i-1]*i)%inf;
}
for(int i=0;i<100010;i++) inv[i]=beki(pr[i],inf-2);

}

*/

//----------------kokomade tenpure------------
int na, nt, ng, nc, m;
string s[200];
map<string, vector<int>> ma;

int dp[210][51][51][51] = {0};

int ch(string s) {
  //	cout<<s<<endl;
  int l = s.length();
  int cv[4] = {0};

  for (int i = 0; i < l; i++) {
    if (s[i] == 'A')
      cv[0] = 1;
    if (s[i] == 'T')
      cv[1] = 1;
    if (s[i] == 'C')
      cv[2] = 1;
    if (s[i] == 'G')
      cv[3] = 1;
  }
  return cv[0] * 8 + cv[1] * 4 + cv[2] * 2 + cv[3];
}

string t, t2;
vector<int> as;
signed main() {
  cin >> na >> nt >> ng >> nc >> m;
  getline(cin, s[0]);
  for (int i = 1; i <= m; i++) {
    getline(cin, s[i]);
    s[i] += " ";
  }

  //	s[m] +=" ";

  for (int i = m; i >= 1; i--) {
    as.clear();

    vector<int> z;
    for (int j = 0; j < s[i].length() - 1; j++)
      if (s[i][j] == ' ')
        z.pb(j);
    z.pb(s[i].length() - 1);

    t = s[i].substr(0, z[0] - 1);
    //	cout<<"t "<<t<<endl;
    for (int j = 1; j < z.size(); j++) {

      t2 = s[i].substr(z[j - 1] + 1, z[j] - z[j - 1] - 1);
      //		cout<<"t2 "<<t2<<endl;
      if (t2[0] == '[' && t2[t2.length() - 1] == ']') {

        as.pb(ch(t2));
      } else {
        //		cout<<"sss"<<ma["a"].size()<<endl;
        vector<int> y = ma[t2];

        for (int ii = 0; ii < y.size(); ii++) {
          as.pb(y[ii]);
        }
      }

      //	cout<<"assize "<<as.size()<<endl;
    }
    //		cout<<t<<" "<<as.size()<<endl;
    ma[t] = as;
    if (as.size() > 200) {
      cout << 0 << endl;
      return 0;
    }
  }
  //	cout<<as.size()<<endl;
  if (as.size() != na + nt + nc + ng) {
    cout << 0 << endl;
    return 0;
  }

  dp[0][0][0][0] = 1;

  int r[4] = {0};
  for (int i = 0; i < as.size(); i++) {
    if (as[i] % 2 == 0)
      r[3] = 0;
    else
      r[3] = 1;
    as[i] /= 2;
    if (as[i] % 2 == 0)
      r[2] = 0;
    else
      r[2] = 1;
    as[i] /= 2;
    if (as[i] % 2 == 0)
      r[1] = 0;
    else
      r[1] = 1;
    as[i] /= 2;
    if (as[i] % 2 == 0)
      r[0] = 0;
    else
      r[0] = 1;
    //		for(int j=0;j<4;j++) cout<<r[j]<<" ";
    //		cout<<endl;

    for (int aa = 0; aa <= 50; aa++)
      for (int tt = 0; tt <= 50; tt++)
        for (int cc = 0; cc <= 50; cc++) {
          if (dp[i][aa][tt][cc] == 0)
            continue;
          for (int j = 0; j < 4; j++) {
            if (r[j] == 0)
              continue;
            if (j == 0 && aa + 1 <= 50) {
              dp[i + 1][aa + 1][tt][cc] += dp[i][aa][tt][cc];
              dp[i + 1][aa + 1][tt][cc] %= inf;
            }
            if (j == 1 && tt + 1 <= 50) {
              dp[i + 1][aa][tt + 1][cc] += dp[i][aa][tt][cc];
              dp[i + 1][aa][tt + 1][cc] %= inf;
            }
            if (j == 2 && cc + 1 <= 50) {
              dp[i + 1][aa][tt][cc + 1] += dp[i][aa][tt][cc];
              dp[i + 1][aa][tt][cc + 1] %= inf;
            }
            if (j == 3) {
              dp[i + 1][aa][tt][cc] += dp[i][aa][tt][cc];
              dp[i + 1][aa][tt][cc] %= inf;
            }
          }
        }
  }

  cout << dp[as.size()][na][nt][nc] << endl;
  return 0;
}