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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <vector>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

int main() {
  for (int n; scanf("%d", &n), n;) {
    static ll b[32000];
    int m = n * (n + 1) / 2;
    rep(i, m) scanf("%lld", b + i);

    int n_ev = 0, n_od = 0;
    static ll b_ev[250], b_od[32000];
    rep(i, m) {
      if (b[i] % 2 == 0)
        b_ev[n_ev++] = b[i];
      else
        b_od[n_od++] = b[i];
    }

    sort(b_ev, b_ev + n_ev);
    sort(b_od, b_od + n_od);

    vector<ll> a0_cand;
    rep(j, n_ev) rep(i, j) {
      ll x = b_ev[i], y = b_ev[j], z = b_od[0], g;
      g = gcd(x, z);
      x /= g;
      z /= g;
      g = gcd(y, z);
      y /= g;
      z /= g;
      if (z == 1) {
        ll a0 = (ll)(sqrt(x) * sqrt(y) + 0.5);
        for (ll t = max(a0 - 7, 2LL); t <= a0 + 7; t++) {
          if (t % 2 == 0 && t * t == x * y)
            a0_cand.push_back(t);
        }
      }
    }
    // puts("cand");
    // rep(i,a0_cand.size()) printf("%lld ",a0_cand[i]); puts("");
    ll a0;
    static ll a_od[250];
    rep(i, a0_cand.size()) {
      a0 = a0_cand[i];

      rep(j, n) a_od[j] = b_ev[j] / a0;

      int n_od2 = 0;
      static ll b_od2[32000];
      rep(k, n_ev) rep(j, k) b_od2[n_od2++] = a_od[j] * a_od[k];
      sort(b_od2, b_od2 + n_od2);

      bool ok = true;
      rep(j, n_od) if (b_od[j] != b_od2[j]) {
        ok = false;
        break;
      }
      if (ok)
        break;

      // bool ok=true;
      // rep(j,300){
      // int k1=rand()%n;
      // int k2=rand()%n;
      // if(k1>=k2){ j--; continue; }
      // ll b_rnd=a_od[k1]*a_od[k2];
      // if(!binary_search(b_od,b_od+n_od,b_rnd)) ok=false;
      // }
      // if(ok) break;
    }

    printf("%lld\\n", a0);
    rep(i, n_ev) printf("%lld%c", a_od[i], i < n_ev - 1 ? ' ' : '\\n');
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <vector>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

vector<ll> divisor(ll a) {
  vector<ll> res;
  for (ll i = 1; i * i <= a; i++)
    if (a % i == 0) {
      res.push_back(i);
      if (i * i < a)
        res.push_back(a / i);
    }
  return res;
}

int main() {
  for (int n; scanf("%d", &n), n;) {
    static ll b[32000];
    int m = n * (n + 1) / 2;
    rep(i, m) scanf("%lld", b + i);

    ll G = -1;
    int n_ev = 0, n_od = 0;
    static ll b_ev[250], b_od[32000];
    rep(i, m) {
      if (b[i] % 2 == 0) {
        if (G == -1)
          G = b[i];
        else
          G = gcd(G, b[i]);
        b_ev[n_ev++] = b[i];
      } else {
        b_od[n_od++] = b[i];
      }
    }

    sort(b_ev, b_ev + n_ev);
    sort(b_od, b_od + n_od);

    ll a0;
    vector<ll> divs = divisor(G);
    sort(divs.begin(), divs.end());
    rep(i, divs.size()) {
      a0 = divs[i];

      static ll a_od[250];
      rep(j, n) a_od[j] = b_ev[j] / a0;

      bool ok = true;
      rep(j, 10) {
        int k1 = rand() % n;
        int k2 = rand() % n;
        ll b_rnd = a_od[k1] * a_od[k2];
        if (!binary_search(b_od, b_od + n_od, b_rnd))
          ok = false;
      }
      if (ok)
        break;
    }

    printf("%lld\\n", a0);
    rep(i, n_ev) printf("%lld%c", b_ev[i] / a0, i < n_ev - 1 ? ' ' : '\\n');
  }

  return 0;
}