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

/*
 *       Author:  8mao
 * Created Time:  2014/3/16 13:46:42
 *    File Name:  1346.cpp
 */
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> PII;
#define INF 1 << 30
#define LL long long
#define MOD 1000000007
#define VI vector<int>
#define VLL vector<LL>
#define VS vector<string>
#define PII pair<int, int>

#define F first
#define S second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define up upper_bound
#define lowbit(x) (x & -x)
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define clr(x) (x).clear()
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define mem(x, y) memset(x, y, sizeof(x))
#define forall(it, c)                                                          \\
  for (typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)

#define N 305
LL b[N][N], a[N];

LL gcd(LL a, LL b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

LL calc(LL a, LL b, LL c) {
  // printf ("%I64d %I64d %I64d\\n", a, b, c);
  LL g = gcd(a, c);
  a /= g, c /= g;
  g = gcd(b, c);
  b /= g, c /= g;
  return (LL)sqrt(a * b * 1.0);
}

int main() {
  // freopen("in.txt","r",stdin);
  int i, j, n;
  while (scanf("%d", &n) != EOF && n) {
    mem(a, 0);
    for (i = 0; i < n; i++)
      for (j = i + 1; j <= n; j++)
        scanf("%lld", &b[i][j]);
    a[0] = calc(b[0][1], b[0][2], b[1][2]);
    for (i = 1; i <= n; i++)
      a[i] = b[0][i] / a[0];
    printf("%lld\\n", a[0]);
    sort(a + 1, a + n + 1);
    for (i = 1; i <= n; i++)
      printf("%lld%c", a[i], i == n ? '\\n' : ' ');
  }
  return 0;
}

Error: TLE

Fixed submission:

#include "math.h"
#include "stdio.h"
#include <algorithm>
using namespace std;
long long b[450000];
long long odd[450000];
long long even[450000];
long long ans[450000];

long long judge(long long n) {
  long long i;
  long long tmp;
  if (n == 1)
    return 1;
  tmp = sqrt(n * 1.0);
  if (tmp * tmp == n)
    tmp = tmp - 1;
  for (i = tmp; i >= 1; i--) {
    if (n % i == 0)
      return i;
  }

  return -1;
}
bool cmp(long long a, long long b) { return a < b; }
long long GCD(long long M, int N) {
  long long Rem;
  while (N > 0) {
    Rem = M % N;
    M = N;
    N = Rem;
  }
  return M;
}
int main() {
  int i, k;
  long long n;
  long long max;
  int even_count;
  int odd_count;
  long long ans_even;
  long long ans_count;
  long long tmp;
  int flag;
  int flag2;
  int flag3;
  while (scanf("%lld", &n) != EOF) {
    if (n == 0)
      break;
    ans_count = 0;
    even_count = 0;
    odd_count = 0;
    max = -1;
    n = n * (n + 1) / 2;
    for (i = 0; i < n; i++) {

      scanf("%lld", &b[i]);
      if (b[i] % 2 == 0) {
        if (max < b[i]) {
          max = b[i];
        }
        even[even_count++] = b[i];
      } else {
        odd[odd_count++] = b[i];
      }
    }
    sort(even, even + even_count, cmp);
    sort(odd, odd + odd_count, cmp);
    if (even_count == 1) {
      ans_even = even[0];
    } else {
      tmp = even[0];
      for (i = 0; i < even_count; i++) {
        tmp = GCD(tmp, even[i]);
      }
      ans_even = tmp;
    }

    for (i = 0; i < even_count; i++) {
      if (even[i] == 0)
        continue;
      flag = 0;
      tmp = even[i] / ans_even;
      for (k = ans_count - 1; k >= 0; k--) {
        if (tmp == ans[k]) {
          flag = 1;
          break;
        }
      }
      if (!flag) {
        ans[ans_count++] = tmp;
      }
    }
    for (i = 0; i < odd_count; i++) {
      flag2 = 0;
      for (k = ans_count - 1; k >= 0; k--) {
        if (odd[k] % ans[k] == 0) {
          flag2 = 1;
          tmp = odd[k] / ans[k];
          break;
        }
      }
      if (flag2) {
        flag3 = 0;
        for (k = ans_count - 1; k >= 0; k--) {
          if (tmp % ans[k] == 0) {
            flag3 = 1;
            break;
          }
        }
        if (!flag3) {
          ans[ans_count++] = tmp;
        }
      } else {
        tmp = judge(odd[i]);
        ans[ans_count++] = tmp;
        ans[ans_count++] = odd[i] / tmp;
      }
    }
    printf("%lld\\n", ans_even);
    sort(ans, ans + ans_count, cmp);
    for (i = 0; i < ans_count; i++) {
      if (i != 0)
        printf(" ");
      printf("%lld", ans[i]);
    }
    printf("\\n");
  }

  return 0;
}