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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

typedef long long LL;
typedef pair<int, int> P;
typedef pair<LL, LL> PLL;

LL gcd(LL x, LL y) {
  if (x < y) {
    swap(x, y);
  }
  if (y == 0) {
    return x;
  }
  return gcd(y, x % y);
}

struct mobile {
  int lb;
  int rb;
  LL lm;
  LL rm;
};

int N;
mobile ms[110];

int get_root() {
  for (int j = 0; j < N; ++j) {
    bool found = false;
    for (int k = 0; k < N; ++k) {
      if (ms[k].lm == j || ms[k].rm == j) {
        found = true;
        break;
      }
    }
    if (!found) {
      return j;
    }
  }
  return -1;
}

LL rec(int x) {
  mobile &m = ms[x];

  LL t = gcd(m.lb, m.rb);

  if (m.lm == -1 && m.rm == -1) {
    return (m.lb + m.rb) / t;
  }

  LL lw, rw, z;
  if (m.lm != -1 && m.rm == -1) {
    lw = rec(m.lm);
    z = (lw * m.lb * m.rb) / gcd(lw * m.lb, m.rb);
    lw *= z / (lw * m.lb);
    rw = lw * m.lb / m.rb;
  } else if (m.lm == -1 && m.rm != -1) {
    rw = rec(m.rm);
    z = (rw * m.rb * m.lb) / gcd(rw * m.rb, m.lb);
    rw *= z / (rw * m.rb);
    lw = rw * m.rb / m.lb;
  } else {
    lw = rec(m.lm);
    rw = rec(m.rm);
    LL z = lw * m.lb / gcd(lw * m.lb, rw * m.rb) * rw * m.rb;
    lw *= z / (lw * m.lb);
    rw *= z / (rw * m.rb);
  }

  assert(lw * m.lb == rw * m.rb);
  return lw + rw;
}

bool solve() {
  cin >> N;
  if (N == 0) {
    return false;
  }
  for (int j = 0; j < N; ++j) {
    cin >> ms[j].lb >> ms[j].rb >> ms[j].lm >> ms[j].rm;
    --ms[j].lm;
    --ms[j].rm;
  }

  LL root = get_root();
  assert(root != -1);

  cout << rec(root) << endl;

  return true;
}

int main() {
  while (solve())
    ;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

typedef long long LL;
typedef pair<int, int> P;
typedef pair<LL, LL> PLL;

LL gcd(LL x, LL y) {
  if (x < y) {
    swap(x, y);
  }
  if (y == 0) {
    return x;
  }
  return gcd(y, x % y);
}

struct mobile {
  int lb;
  int rb;
  LL lm;
  LL rm;
};

int N;
mobile ms[110];

int get_root() {
  for (int j = 0; j < N; ++j) {
    bool found = false;
    for (int k = 0; k < N; ++k) {
      if (ms[k].lm == j || ms[k].rm == j) {
        found = true;
        break;
      }
    }
    if (!found) {
      return j;
    }
  }
  return -1;
}

LL rec(int x) {
  mobile &m = ms[x];

  LL t = gcd(m.lb, m.rb);

  if (m.lm == -1 && m.rm == -1) {
    return (m.lb + m.rb) / t;
  }

  LL lw, rw;
  if (m.lm != -1 && m.rm == -1) {
    lw = rec(m.lm) * (m.rb / t);
    rw = (lw * m.lb) / m.rb;
  } else if (m.lm == -1 && m.rm != -1) {
    rw = rec(m.rm) * (m.lb / t);
    lw = (rw * m.rb) / m.lb;
  } else {
    lw = rec(m.lm) * (m.rb / t);
    rw = rec(m.rm) * (m.lb / t);
    int u = gcd(lw * m.lb, rw * m.rb);
    int tmp = lw;
    lw *= (rw * m.rb) / u;
    rw *= (tmp * m.lb) / u;
  }

  assert(lw * m.lb == rw * m.rb);
  return lw + rw;
}

bool solve() {

  cin >> N;
  if (N == 0) {
    return false;
  }
  for (int j = 0; j < N; ++j) {
    cin >> ms[j].lb >> ms[j].rb >> ms[j].lm >> ms[j].rm;
    --ms[j].lm;
    --ms[j].rm;
  }

  int root = get_root();

  cout << rec(root) << endl;

  return true;
}

int main() {
  while (solve())
    ;
}