Problem p02692 (C++)

Buggy submission (status: Runtime Error):
#undef NDEBUG

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef vector<vector<vector<ll>>> vvvll;
typedef vector<bool> vb;
typedef vector<vector<bool>> vvb;
typedef vector<vector<vector<bool>>> vvvb;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
typedef vector<vpll> vvpll;
typedef vector<double> vd;
typedef vector<vd> vdd;

#define FOR(i, x, y) for (ll i = (ll)x; i < (ll)y; ++i)
#define REP(i, y) FOR(i, 0, y)
#define RFOR(i, x, y) for (ll i = (ll)x; i >= (ll)y; --i)
#define RREP(i, x) RFOR(i, x, 0)
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define debug_print(x...)                                                      \
  cerr << "line " << __LINE__ << " : ";                                        \
  debug_print_in(x);

template <typename First> void debug_print_in(First first) {
  cerr << first << endl;
  return;
}

template <typename First, typename... Rest>
void debug_print_in(First first, Rest... rest) {
  cerr << first << " ";
  debug_print_in(rest...);
  return;
}

void IN(void) { return; }

template <typename First, typename... Rest>
void IN(First &first, Rest &...rest) {
  cin >> first;
  IN(rest...);
  return;
}

template <typename First> void OUT(First first) {
  cout << first << endl;
  return;
}

template <typename First, typename... Rest>
void OUT(First first, Rest... rest) {
  cout << first << " ";
  OUT(rest...);
  return;
}

template <class t, class u> void chmax(t &a, u b) {
  if (a < b)
    a = b;
};
template <class t, class u> void chmin(t &a, u b) {
  if (a > b)
    a = b;
};
int popcount(int t) { return __builtin_popcount(t); }  // GCC
int popcount(ll t) { return __builtin_popcountll(t); } // GCC

template <typename T> void vec_print(vector<T> VEC) {
  REP(i, VEC.size()) { cerr << VEC[i] << " "; }
  cerr << endl;
};

template <typename T>
void mat_print(vector<vector<T>> MAT){
    REP(i, MAT.size()){REP(j, MAT[i].size()){cerr << MAT[i][j] << " ";
}
cerr << endl;
}
}
;

ll N, A, B, C;
ll ABC;
vll s;
vvll dp;

ll dp_search(ll index) {
  if (index >= N) {
    return index;
  }
  if (s.at(index) == 1) {
    dp[index + 1][0] = dp[index][5];
    dp[index + 1][1] = dp[index][5];
    dp[index + 1][2] = 0;
    dp[index + 1][3] = dp[index][4];
    dp[index + 1][4] = dp[index][3];
    dp[index + 1][5] = dp[index][0] | dp[index][1];
  } else if (s.at(index) == 2) {
    dp[index + 1][0] = dp[index][4];
    dp[index + 1][1] = 0;
    dp[index + 1][2] = dp[index][4];
    dp[index + 1][3] = dp[index][5];
    dp[index + 1][4] = dp[index][0] | dp[index][2];
    dp[index + 1][5] = dp[index][3];
  } else if (s.at(index) == 3) {
    dp[index + 1][0] = 0;
    dp[index + 1][1] = dp[index][3];
    dp[index + 1][2] = dp[index][3];
    dp[index + 1][3] = dp[index][1] | dp[index][2];
    dp[index + 1][4] = dp[index][5];
    dp[index + 1][5] = dp[index][4];
  }

  ll status = -1;
  for (int k = 0; k < 6; ++k) {
    if (dp[index + 1][k] > 0)
      status = k;
  }
  if (status < 0)
    return index;

  return dp_search(index + 1);
}

vvll hoge = {{2, 0, 0}, {0, 2, 0}, {0, 0, 2}, {0, 1, 1}, {1, 0, 1}, {1, 1, 0}};

void rev(vvll &ans, ll index, ll state) {
  ans.push_back(hoge.at(state));
  if (index < 0)
    return;
  ll new_state = -1;
  if (s.at(index) == 1) {
    switch (state) {
    case 0:
      new_state = 5;
      break;
    case 1:
      new_state = 5;
      break;
    case 2:
      break;
    case 3:
      new_state = 4;
      break;
    case 4:
      new_state = 3;
      break;
    case 5:
      if (dp.at(index).at(0) > 0) {
        new_state = 0;
      } else {
        new_state = 1;
      }
      break;
    }
  } else if (s.at(index) == 2) {
    switch (state) {
    case 0:
      new_state = 4;
      break;
    case 1:
      break;
    case 2:
      new_state = 4;
      break;
    case 3:
      new_state = 5;
      break;
    case 4:
      if (dp.at(index).at(0) > 0) {
        new_state = 0;
      } else {
        new_state = 2;
      }
      break;
    case 5:
      new_state = 3;
      break;
    }
  } else {
    switch (state) {
    case 0:
      break;
    case 1:
      new_state = 3;
      break;
    case 2:
      new_state = 3;
      break;
    case 3:
      if (dp.at(index).at(1) > 0) {
        new_state = 1;
      } else {
        new_state = 2;
      }
      break;
    case 4:
      new_state = 5;
      break;
    case 5:
      new_state = 4;
      break;
    }
  }

  rev(ans, index - 1, new_state);
  return;
}

vvll tmp(0);

// vvll search(void){
void search(void) {
  /*
  {
    ll status = -1;
    for(ll k=0; k<6; ++k){
      if(dp[0][k] > 0) status = k;
    }
    assert(status>=0);
  }
  */

  ll val = dp_search(0);

  assert(val > N - 1);

  ll state = -1;
  REP(i, 6) {
    if (dp[N][i] > 0) {
      state = i;
    }
  }

  // assert(state>=0);

  if (state == -1)
    return;

  rev(tmp, N - 1, state);
  reverse(ALL(tmp));

  return;
}

int main() {
  cin.tie(0); // cut the cin and cout (default, std::flush is performed after
              // std::cin)
  ios::sync_with_stdio(
      false); // cut the iostream and stdio (DON'T endl; BUT "\n";)

  IN(N, A, B, C);

  ll A_init = A;
  ll B_init = B;
  ll C_init = C;

  ABC = A + B + C;
  // ABC = 1 -> do
  // ABC >= 3 -> go lower
  // ABC == 2 -> ?

  s.resize(N + 1, -1);
  dp.resize(N + 10, vll(6, 0));

  if (A == 2 && B == 0 && C == 0) {
    dp[0][0] = 1;
  } else if (A == 0 && B == 2 && C == 0) {
    dp[0][1] = 1;
  } else if (A == 0 && B == 0 && C == 2) {
    dp[0][2] = 1;
  } else if (A == 0 && B == 1 && C == 1) {
    dp[0][3] = 1;
  } else if (A == 1 && B == 0 && C == 1) {
    dp[0][4] = 1;
  } else if (A == 1 && B == 1 && C == 0) {
    dp[0][5] = 1;
  }

  REP(i, N) {
    string str;
    IN(str);
    if (str == "AB") {
      s[i] = 1;
    } else if (str == "AC") {
      s[i] = 2;
    } else {
      s[i] = 3;
    }
  }

  vll ans(N, -1);

  if (ABC <= 1 || ABC >= 3) {
    //{{{
    REP(i, N) {
      switch (s[i]) {
      case 1:
        if (A == 0 && B == 0) {
          OUT("No");
          return 0;
        }
        if (A > B) {
          A--;
          B++;
          ans[i] = 1;
        } else {
          A++;
          B--;
          ans[i] = 0;
        }
        break;
      case 2:
        if (A == 0 && C == 0) {
          OUT("No");
          return 0;
        }
        if (A > C) {
          A--;
          C++;
          ans[i] = 2;
        } else {
          A++;
          C--;
          ans[i] = 0;
        }
        break;
      case 3:
        if (B == 0 && C == 0) {
          OUT("No");
          return 0;
        }
        if (B > C) {
          B--;
          C++;
          ans[i] = 2;
        } else {
          B++;
          C--;
          ans[i] = 1;
        }
      }
    }
    //}}}
  } else {
    // vvll tmp = search();
    search();

    // assert(tmp.size()>0);

    if (tmp.size() == 0) {
      OUT("No");
      return 0;
    }
    // mat_print(dp);
    // mat_print(tmp);
    for (ll i = 0; i < N; ++i) {
      REP(j, 3) {
        if (tmp.at(i + 1).at(j) - tmp.at(i).at(j) > 0) {
          ans[i] = j;
          break;
        }
      }
    }
  }

  printf("Yes\n");
  // debug_print(A_init, B_init, C_init);
  REP(i, N) {
    if (ans[i] == 0) {
      printf("A\n");
      A_init++;
      if (s[i] == 1)
        B_init--;
      else
        C_init--;
    } else if (ans[i] == 1) {
      printf("B\n");
      B_init++;
      if (s[i] == 1)
        A_init--;
      else
        C_init--;
    } else if (ans[i] == 2) {
      printf("C\n");
      C_init++;
      if (s[i] == 2)
        A_init--;
      else
        B_init--;
    }
    // debug_print(A_init, B_init, C_init);
  }

  return 0;
}


Fixed submission:
#undef NDEBUG

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef vector<vector<vector<ll>>> vvvll;
typedef vector<bool> vb;
typedef vector<vector<bool>> vvb;
typedef vector<vector<vector<bool>>> vvvb;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
typedef vector<vpll> vvpll;
typedef vector<double> vd;
typedef vector<vd> vdd;

#define FOR(i, x, y) for (ll i = (ll)x; i < (ll)y; ++i)
#define REP(i, y) FOR(i, 0, y)
#define RFOR(i, x, y) for (ll i = (ll)x; i >= (ll)y; --i)
#define RREP(i, x) RFOR(i, x, 0)
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define debug_print(x...)                                                      \
  cerr << "line " << __LINE__ << " : ";                                        \
  debug_print_in(x);

template <typename First> void debug_print_in(First first) {
  cerr << first << endl;
  return;
}

template <typename First, typename... Rest>
void debug_print_in(First first, Rest... rest) {
  cerr << first << " ";
  debug_print_in(rest...);
  return;
}

void IN(void) { return; }

template <typename First, typename... Rest>
void IN(First &first, Rest &...rest) {
  cin >> first;
  IN(rest...);
  return;
}

template <typename First> void OUT(First first) {
  cout << first << endl;
  return;
}

template <typename First, typename... Rest>
void OUT(First first, Rest... rest) {
  cout << first << " ";
  OUT(rest...);
  return;
}

template <class t, class u> void chmax(t &a, u b) {
  if (a < b)
    a = b;
};
template <class t, class u> void chmin(t &a, u b) {
  if (a > b)
    a = b;
};
int popcount(int t) { return __builtin_popcount(t); }  // GCC
int popcount(ll t) { return __builtin_popcountll(t); } // GCC

template <typename T> void vec_print(vector<T> VEC) {
  REP(i, VEC.size()) { cerr << VEC[i] << " "; }
  cerr << endl;
};

template <typename T>
void mat_print(vector<vector<T>> MAT){
    REP(i, MAT.size()){REP(j, MAT[i].size()){cerr << MAT[i][j] << " ";
}
cerr << endl;
}
}
;

ll N, A, B, C;
ll ABC;
vll s;
vvll dp;

ll dp_search(ll index) {
  if (index >= N) {
    return index;
  }
  if (s.at(index) == 1) {
    dp[index + 1][0] = dp[index][5];
    dp[index + 1][1] = dp[index][5];
    dp[index + 1][2] = 0;
    dp[index + 1][3] = dp[index][4];
    dp[index + 1][4] = dp[index][3];
    dp[index + 1][5] = dp[index][0] | dp[index][1];
  } else if (s.at(index) == 2) {
    dp[index + 1][0] = dp[index][4];
    dp[index + 1][1] = 0;
    dp[index + 1][2] = dp[index][4];
    dp[index + 1][3] = dp[index][5];
    dp[index + 1][4] = dp[index][0] | dp[index][2];
    dp[index + 1][5] = dp[index][3];
  } else if (s.at(index) == 3) {
    dp[index + 1][0] = 0;
    dp[index + 1][1] = dp[index][3];
    dp[index + 1][2] = dp[index][3];
    dp[index + 1][3] = dp[index][1] | dp[index][2];
    dp[index + 1][4] = dp[index][5];
    dp[index + 1][5] = dp[index][4];
  }

  ll status = -1;
  for (int k = 0; k < 6; ++k) {
    if (dp[index + 1][k] > 0)
      status = k;
  }
  if (status < 0)
    return index;

  return dp_search(index + 1);
}

vvll hoge = {{2, 0, 0}, {0, 2, 0}, {0, 0, 2}, {0, 1, 1}, {1, 0, 1}, {1, 1, 0}};

void rev(vvll &ans, ll index, ll state) {
  ans.push_back(hoge.at(state));
  if (index < 0)
    return;
  ll new_state = -1;
  if (s.at(index) == 1) {
    switch (state) {
    case 0:
      new_state = 5;
      break;
    case 1:
      new_state = 5;
      break;
    case 2:
      break;
    case 3:
      new_state = 4;
      break;
    case 4:
      new_state = 3;
      break;
    case 5:
      if (dp.at(index).at(0) > 0) {
        new_state = 0;
      } else {
        new_state = 1;
      }
      break;
    }
  } else if (s.at(index) == 2) {
    switch (state) {
    case 0:
      new_state = 4;
      break;
    case 1:
      break;
    case 2:
      new_state = 4;
      break;
    case 3:
      new_state = 5;
      break;
    case 4:
      if (dp.at(index).at(0) > 0) {
        new_state = 0;
      } else {
        new_state = 2;
      }
      break;
    case 5:
      new_state = 3;
      break;
    }
  } else {
    switch (state) {
    case 0:
      break;
    case 1:
      new_state = 3;
      break;
    case 2:
      new_state = 3;
      break;
    case 3:
      if (dp.at(index).at(1) > 0) {
        new_state = 1;
      } else {
        new_state = 2;
      }
      break;
    case 4:
      new_state = 5;
      break;
    case 5:
      new_state = 4;
      break;
    }
  }

  rev(ans, index - 1, new_state);
  return;
}

vvll tmp(0);

// vvll search(void){
void search(void) {
  /*
  {
    ll status = -1;
    for(ll k=0; k<6; ++k){
      if(dp[0][k] > 0) status = k;
    }
    assert(status>=0);
  }
  */

  ll val = dp_search(0);

  // assert(val > N-1);

  ll state = -1;
  REP(i, 6) {
    if (dp[N][i] > 0) {
      state = i;
    }
  }

  // assert(state>=0);

  if (state == -1)
    return;

  rev(tmp, N - 1, state);
  reverse(ALL(tmp));

  return;
}

int main() {
  cin.tie(0); // cut the cin and cout (default, std::flush is performed after
              // std::cin)
  ios::sync_with_stdio(
      false); // cut the iostream and stdio (DON'T endl; BUT "\n";)

  IN(N, A, B, C);

  ll A_init = A;
  ll B_init = B;
  ll C_init = C;

  ABC = A + B + C;
  // ABC = 1 -> do
  // ABC >= 3 -> go lower
  // ABC == 2 -> ?

  s.resize(N + 1, -1);
  dp.resize(N + 10, vll(6, 0));

  if (A == 2 && B == 0 && C == 0) {
    dp[0][0] = 1;
  } else if (A == 0 && B == 2 && C == 0) {
    dp[0][1] = 1;
  } else if (A == 0 && B == 0 && C == 2) {
    dp[0][2] = 1;
  } else if (A == 0 && B == 1 && C == 1) {
    dp[0][3] = 1;
  } else if (A == 1 && B == 0 && C == 1) {
    dp[0][4] = 1;
  } else if (A == 1 && B == 1 && C == 0) {
    dp[0][5] = 1;
  }

  REP(i, N) {
    string str;
    IN(str);
    if (str == "AB") {
      s[i] = 1;
    } else if (str == "AC") {
      s[i] = 2;
    } else {
      s[i] = 3;
    }
  }

  vll ans(N, -1);

  if (ABC <= 1 || ABC >= 3) {
    //{{{
    REP(i, N) {
      switch (s[i]) {
      case 1:
        if (A == 0 && B == 0) {
          OUT("No");
          return 0;
        }
        if (A > B) {
          A--;
          B++;
          ans[i] = 1;
        } else {
          A++;
          B--;
          ans[i] = 0;
        }
        break;
      case 2:
        if (A == 0 && C == 0) {
          OUT("No");
          return 0;
        }
        if (A > C) {
          A--;
          C++;
          ans[i] = 2;
        } else {
          A++;
          C--;
          ans[i] = 0;
        }
        break;
      case 3:
        if (B == 0 && C == 0) {
          OUT("No");
          return 0;
        }
        if (B > C) {
          B--;
          C++;
          ans[i] = 2;
        } else {
          B++;
          C--;
          ans[i] = 1;
        }
      }
    }
    //}}}
  } else {
    // vvll tmp = search();
    search();

    // assert(tmp.size()>0);

    if (tmp.size() == 0) {
      OUT("No");
      return 0;
    }
    // mat_print(dp);
    // mat_print(tmp);
    for (ll i = 0; i < N; ++i) {
      REP(j, 3) {
        if (tmp.at(i + 1).at(j) - tmp.at(i).at(j) > 0) {
          ans[i] = j;
          break;
        }
      }
    }
  }

  printf("Yes\n");
  // debug_print(A_init, B_init, C_init);
  REP(i, N) {
    if (ans[i] == 0) {
      printf("A\n");
      A_init++;
      if (s[i] == 1)
        B_init--;
      else
        C_init--;
    } else if (ans[i] == 1) {
      printf("B\n");
      B_init++;
      if (s[i] == 1)
        A_init--;
      else
        C_init--;
    } else if (ans[i] == 2) {
      printf("C\n");
      C_init++;
      if (s[i] == 2)
        A_init--;
      else
        B_init--;
    }
    // debug_print(A_init, B_init, C_init);
  }

  return 0;
}