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

#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

struct Node {
  Node *l;
  Node *r;
  Node() { l = r = NULL; }
};

Node *build(char s[], int l, int r) {
  if (r < l)
    return NULL;
  Node *p = new Node();
  int cnt = 0;
  for (int i = l + 1; i < r; ++i) {
    if (s[i] == '(') {
      cnt++;
      continue;
    }
    if (s[i] == ')') {
      cnt--;
      continue;
    }
    if (s[i] == ',' && cnt == 0) {
      p->l = build(s, l + 1, i - 1);
      p->r = build(s, i + 1, r - 1);
      break;
    }
  }
  return p;
}

Node *getInter(Node *a, Node *b) {
  Node *p = new Node();
  if (a->l != NULL && b->l != NULL) {
    p->l = getInter(a->l, b->l);
  } else
    p->l = NULL;
  if (a->r != NULL && b->r != NULL) {
    p->r = getInter(a->r, b->r);
  } else
    p->r = NULL;
  return p;
}

Node *getUnion(Node *a, Node *b) {
  Node *p = new Node();
  if (a != NULL && b != NULL) {
    if (a->l != NULL || b->l != NULL) {
      p->l = getUnion(a->l, b->l);
    } else
      p->l = NULL;
    if (a->r != NULL || b->r != NULL) {
      p->r = getUnion(a->r, b->r);
    } else
      p->r = NULL;
  } else if (a == NULL) {
    if (b->l != NULL)
      p->l = getUnion(NULL, b->l);
    else
      p->l = NULL;
    if (b->r != NULL)
      p->r = getUnion(NULL, b->r);
    else
      p->r = NULL;
  } else {
    if (a->l != NULL)
      p->l = getUnion(a->l, NULL);
    else
      p->l = NULL;
    if (a->r != NULL)
      p->r = getUnion(a->r, NULL);
    else
      p->r = NULL;
  }
  return p;
}

string getStr(Node *p) {
  if (p == NULL) {
    return "";
  } else
    return "(" + getStr(p->l) + "," + getStr(p->r) + ")";
}

char a[3000], b[3000];

int main() {
  char op;
  while (scanf("%c %s %s", &op, a, b) != EOF) {
    getchar();
    int la = strlen(a), lb = strlen(b);
    Node *ra = build(a, 0, la - 1);
    Node *rb = build(b, 0, lb - 1);
    Node *root = NULL;
    if (op == 'i')
      root = getInter(ra, rb);
    else
      root = getUnion(ra, rb);
    string res = getStr(root);
    printf("%s\\n", res.c_str());
  }
  return 0;
}

/*
i ((,),(,)) ((,(,)),)
u ((,),(,)) ((,(,)),)
i (((,),),) (,(,(,)))
u (((,),),) (,(,(,)))
*/

Error: WA

Fixed submission:

#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

struct Node {
  Node *l;
  Node *r;
  Node() { l = r = NULL; }
};

Node *build(char s[], int l, int r) {
  if (r < l)
    return NULL;
  Node *p = new Node();
  int cnt = 0;
  for (int i = l + 1; i < r; ++i) {
    if (s[i] == '(') {
      cnt++;
      continue;
    }
    if (s[i] == ')') {
      cnt--;
      continue;
    }
    if (s[i] == ',' && cnt == 0) {
      p->l = build(s, l + 1, i - 1);
      p->r = build(s, i + 1, r - 1);
      break;
    }
  }
  return p;
}

Node *getInter(Node *a, Node *b) {
  Node *p = new Node();
  if (a->l != NULL && b->l != NULL) {
    p->l = getInter(a->l, b->l);
  } else
    p->l = NULL;
  if (a->r != NULL && b->r != NULL) {
    p->r = getInter(a->r, b->r);
  } else
    p->r = NULL;
  return p;
}

Node *getUnion(Node *a, Node *b) {
  Node *p = new Node();
  if ((a != NULL && a->l != NULL) || (b != NULL && b->l != NULL)) {
    // printf("l\\n");
    p->l = getUnion(a->l, b->l);
  } else
    p->l = NULL;
  if ((a != NULL && a->r != NULL) || (b != NULL && b->r != NULL)) {
    // printf("r\\n");
    p->r = getUnion(a->r, b->r);
  } else
    p->r = NULL;
  return p;
}

string getStr(Node *p) {
  if (p == NULL) {
    return "";
  } else
    return "(" + getStr(p->l) + "," + getStr(p->r) + ")";
}

int main() {
  char op;
  char a[2000], b[2000];
  while (scanf("%c %s %s", &op, a, b) != EOF) {
    getchar();
    printf("%c %s %s\\n", op, a, b);
    int la = strlen(a), lb = strlen(b);
    Node *ra = build(a, 0, la - 1);
    Node *rb = build(b, 0, lb - 1);
    Node *root = NULL;
    if (op == 'i')
      root = getInter(ra, rb);
    else
      root = getUnion(ra, rb);
    string res = getStr(root);
    printf("%s\\n", res.c_str());
  }
  return 0;
}