Problem p00443 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

typedef long long LL;
typedef vector<int> Array;
typedef pair<int, int> P;

const int INF = 1 << 29;
const LL MOD = 100000;
#define rep(i, n) for (int i = 0; i < (int)n; ++i)
#define all(c) (c).begin(), (c).end()

struct edge {
  int to, cost;
  edge(int t, int c) : to(t), cost(c) {}
};

int dxk[] = {1, 1, 1, 0, -1, 0};
int dxg[] = {0, 1, 0, -1, -1, -1};
int dy[] = {-1, 0, 1, 1, 0, -1};

struct node {
  LL value, lw, rw, left, right;
};

LL gcd(LL a, LL b) {
  if (a < b)
    swap(a, b);
  return a % b == 0 ? b : gcd(b, a % b);
}
LL sks(LL a, LL b) {
  LL g = gcd(a, b);
  return a / g * b;
}

LL dfs(int idx, vector<node> &bars) {
  if (idx == -1)
    return 1LL;
  node &node = bars[idx];
  if (node.value != 0)
    return node.value;

  LL r = dfs(node.right, bars), l = dfs(node.left, bars);

  int m = 1;
  while ((r * node.rw * m) % (l * node.lw) != 0)
    m++;
  int lm = r * node.rw * m / (l * node.lw);
  // r*lの最小公倍数を基礎値としてm:nにする
  // LL s = sks(r * node.rw, l * node.lw);
  // return node.value = s / node.rw + s / node.lw;
  return node.value = m * r + lm * l;
}

int main() {
  int n;
  while (cin >> n && n) {
    vector<node> bars(n);
    rep(i, n) {
      int p, q, r, b;
      cin >> p >> q >> r >> b;
      int g = gcd(p, q);
      bars[i].rw = q / g;
      bars[i].lw = p / g;
      bars[i].left = r - 1;
      bars[i].right = b - 1;
    }

    LL ans = 0;
    rep(i, n) ans = max(dfs(i, bars), ans);
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

typedef long long LL;
typedef vector<int> Array;
typedef pair<int, int> P;

const int INF = 1 << 29;
const LL MOD = 100000;
#define rep(i, n) for (int i = 0; i < (int)n; ++i)
#define all(c) (c).begin(), (c).end()

struct edge {
  int to, cost;
  edge(int t, int c) : to(t), cost(c) {}
};

int dxk[] = {1, 1, 1, 0, -1, 0};
int dxg[] = {0, 1, 0, -1, -1, -1};
int dy[] = {-1, 0, 1, 1, 0, -1};

struct node {
  LL value, lw, rw, left, right;
};

LL gcd(LL a, LL b) {
  if (a < b)
    swap(a, b);
  return a % b == 0 ? b : gcd(b, a % b);
}
LL sks(LL a, LL b) {
  LL g = gcd(a, b);
  return a / g * b;
}

LL dfs(int idx, vector<node> &bars) {
  if (idx == -1)
    return 1LL;
  node &node = bars[idx];
  if (node.value != 0)
    return node.value;

  LL r = dfs(node.right, bars), l = dfs(node.left, bars);

  // r*lの最小公倍数を基礎値としてm:nにする
  LL s = sks(r * node.rw, l * node.lw);
  return node.value = s / node.rw + s / node.lw;
}

int main() {
  int n;
  while (cin >> n && n) {
    vector<node> bars(n);
    rep(i, n) {
      int p, q, r, b;
      cin >> p >> q >> r >> b;
      int g = gcd(p, q);
      bars[i].rw = p / g;
      bars[i].lw = q / g;
      bars[i].left = r - 1;
      bars[i].right = b - 1;
    }

    LL ans = 0;
    rep(i, n) ans = max(dfs(i, bars), ans);
    cout << ans << endl;
  }

  return 0;
}