Problem p03300 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
template <typename T> void read(T &t) {
  t = 0;
  char ch = getchar();
  int f = 1;
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  do {
    (t *= 10) += ch - '0';
    ch = getchar();
  } while ('0' <= ch && ch <= '9');
  t *= f;
}
const int maxn = 3010;
int n, s[maxn], tot;
char t[maxn], ans[maxn], res[maxn];
struct node {
  int l, r, flag;
} d[maxn];
bool cmp(char *a, char *b) {
  int t1 = strlen(a + 1), t2 = strlen(b + 1);
  for (int i = 1; i <= max(t1, t2); i++) {
    if (i > t1)
      a[i] = 0;
    if (i > t2)
      b[i] = 0;
    if (a[i] != b[i])
      return a[i] < b[i];
  }
  return 1;
}
bool cmp2(char *a, char *b) {
  int t1 = strlen(a + 1), t2 = strlen(b + 1);
  for (int i = 1; i <= t2; i++) {
    if (i > t1)
      a[i] = 0;
    if (a[i] != b[i])
      return a[i] < b[i];
  }
  return 1;
}
char tmp[maxn];
int id[maxn];
void eq(char *a, char *b) {
  int len = strlen(b + 1);
  for (int i = 1; i <= len; i++)
    a[i] = b[i];
  a[len + 1] = 0;
}
void solve(int l, int r) {
  // [l,r] has more 'b' than 'a' in every prefix
  int t1 = 0, t2 = 0, len;
  res[1] = 'a' - 1;
  res[2] = 0;
  for (int i = l; i <= r; i++) {
    if (t[i] == 'a')
      id[i] = ++t1;
    else
      id[i] = ++t2;
  }
  for (int i = 1; i <= t1; i++) {
    len = 0;
    for (int j = l; j <= r; j++)
      if (id[j] >= i)
        tmp[++len] = t[j];
    tmp[len + 1] = 0;
    // printf("%s\n",tmp+1);
    if (cmp(res, tmp))
      eq(res, tmp);
  }
}
bool mk[maxn];
int dy[maxn];
void solve2(int l, int r) {
  int t1 = 0, t2 = 0;
  for (int i = l; i <= r; i++) {
    if (t[i] == 'a')
      id[i] = ++t1;
    else
      id[i] = ++t2, dy[t2] = i;
  }
  int pos;
  for (int i = l; i <= r; i++) {
    if (!mk[i] && t[i] == 'a') {
      pos = dy[id[i]];
      for (int j = i; j <= pos; j++)
        mk[j] = 1;
      i = pos;
      printf("ab");
    }
  }
}
int main() {
  // freopen("1.txt","r",stdin);
  read(n);
  n *= 2;
  scanf("%s", t + 1);
  int flag = 0, sum = 0;
  for (int i = 1; i <= n; i++) {
    if (t[i] == 'a')
      sum++;
    else
      sum--;
    s[i] = sum;
    if (!flag) {
      if (sum < 0)
        flag = -1;
      else if (sum > 0)
        flag = 1;
    }
    if (sum == 0) {
      tot++;
      d[tot] = (node){d[tot - 1].r + 1, i, flag};
      flag = 0;
    }
  }
  // for (int i=1;i<=tot;i++)
  // printf("%d %d %d\n",d[i].l,d[i].r,d[i].flag);
  int pos = 0, len;
  for (int i = tot; i >= 1; i--) {
    if (d[i].flag == 1)
      continue;
    if (!pos)
      pos = i;
    solve(d[i].l, d[i].r);
    //	printf("res=%s\n",res+1);
    if (cmp2(ans, res)) {
      len = strlen(ans + 1);
      reverse(ans + 1, ans + len + 1);
      for (int j = strlen(res + 1); j >= 1; j--)
        ans[++len] = res[j];
      // printf("ans=%s\n",ans+1);
      ans[len + 1] = 0;
      reverse(ans + 1, ans + len + 1);
    }
  }
  printf("%s", ans + 1);
  for (int i = pos + 1; i <= tot; i++) {
    solve2(d[i].l, d[i].r);
  }
  printf("\n");
  return 0;
}
/*
  0. Enough array size? Enough array size? Enough array size? Interger overflow?

  1. Think TWICE, Code ONCE!
  Are there any counterexamples to your algo?

  2. Be careful about the BOUNDARIES!
  N=1? P=1? Something about 0?

  3. Do not make STUPID MISTAKES!
  Time complexity? Memory usage? Precision error?
*/

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
template <typename T> void read(T &t) {
  t = 0;
  char ch = getchar();
  int f = 1;
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  do {
    (t *= 10) += ch - '0';
    ch = getchar();
  } while ('0' <= ch && ch <= '9');
  t *= f;
}
const int maxn = 6010;
int n, s[maxn], tot;
char t[maxn], ans[maxn], res[maxn];
struct node {
  int l, r, flag;
} d[maxn];
bool cmp(char *a, char *b) {
  int t1 = strlen(a + 1), t2 = strlen(b + 1);
  for (int i = 1; i <= max(t1, t2); i++) {
    if (i > t1)
      a[i] = 0;
    if (i > t2)
      b[i] = 0;
    if (a[i] != b[i])
      return a[i] < b[i];
  }
  return 1;
}
bool cmp2(char *a, char *b) {
  int t1 = strlen(a + 1), t2 = strlen(b + 1);
  for (int i = 1; i <= t2; i++) {
    if (i > t1)
      a[i] = 0;
    if (a[i] != b[i])
      return a[i] < b[i];
  }
  return 1;
}
char tmp[maxn];
int id[maxn];
void eq(char *a, char *b) {
  int len = strlen(b + 1);
  for (int i = 1; i <= len; i++)
    a[i] = b[i];
  a[len + 1] = 0;
}
void solve(int l, int r) {
  // [l,r] has more 'b' than 'a' in every prefix
  int t1 = 0, t2 = 0, len;
  res[1] = 'a' - 1;
  res[2] = 0;
  for (int i = l; i <= r; i++) {
    if (t[i] == 'a')
      id[i] = ++t1;
    else
      id[i] = ++t2;
  }
  for (int i = 1; i <= t1; i++) {
    len = 0;
    for (int j = l; j <= r; j++)
      if (id[j] >= i)
        tmp[++len] = t[j];
    tmp[len + 1] = 0;
    // printf("%s\n",tmp+1);
    if (cmp(res, tmp))
      eq(res, tmp);
  }
}
bool mk[maxn];
int dy[maxn];
void solve2(int l, int r) {
  int t1 = 0, t2 = 0;
  for (int i = l; i <= r; i++) {
    if (t[i] == 'a')
      id[i] = ++t1;
    else
      id[i] = ++t2, dy[t2] = i;
  }
  int pos;
  for (int i = l; i <= r; i++) {
    if (!mk[i] && t[i] == 'a') {
      pos = dy[id[i]];
      for (int j = i; j <= pos; j++)
        mk[j] = 1;
      i = pos;
      printf("ab");
    }
  }
}
int main() {
  // freopen("1.txt","r",stdin);
  read(n);
  n *= 2;
  scanf("%s", t + 1);
  int flag = 0, sum = 0;
  for (int i = 1; i <= n; i++) {
    if (t[i] == 'a')
      sum++;
    else
      sum--;
    s[i] = sum;
    if (!flag) {
      if (sum < 0)
        flag = -1;
      else if (sum > 0)
        flag = 1;
    }
    if (sum == 0) {
      tot++;
      d[tot] = (node){d[tot - 1].r + 1, i, flag};
      flag = 0;
    }
  }
  // for (int i=1;i<=tot;i++)
  // printf("%d %d %d\n",d[i].l,d[i].r,d[i].flag);
  int pos = 0, len;
  for (int i = tot; i >= 1; i--) {
    if (d[i].flag == 1)
      continue;
    if (!pos)
      pos = i;
    solve(d[i].l, d[i].r);
    //	printf("res=%s\n",res+1);
    if (cmp2(ans, res)) {
      len = strlen(ans + 1);
      reverse(ans + 1, ans + len + 1);
      for (int j = strlen(res + 1); j >= 1; j--)
        ans[++len] = res[j];
      // printf("ans=%s\n",ans+1);
      ans[len + 1] = 0;
      reverse(ans + 1, ans + len + 1);
    }
  }
  printf("%s", ans + 1);
  for (int i = pos + 1; i <= tot; i++) {
    solve2(d[i].l, d[i].r);
  }
  printf("\n");
  return 0;
}
/*
  0. Enough array size? Enough array size? Enough array size? Interger overflow?

  1. Think TWICE, Code ONCE!
  Are there any counterexamples to your algo?

  2. Be careful about the BOUNDARIES!
  N=1? P=1? Something about 0?

  3. Do not make STUPID MISTAKES!
  Time complexity? Memory usage? Precision error?
*/