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

#define _GLIBCXX_DEBUG
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
#define rep0(TMS) for (int CNT = 0; CNT < (int)(TMS); CNT++)
#define rep(CNT, GOAL) for (int CNT = 0; CNT < (int)(GOAL); CNT++)
#define rep2(CNT, START, GOAL)                                                 \\
  for (int CNT = (int)(START); CNT < (int)(GOAL); CNT++)
#define rep3(CNT, START, GOAL)                                                 \\
  for (int CNT = (int)(START); CNT > (int)(GOAL); CNT--)
#define all(CONT) begin(CONT), end(CONT)
#define itrep(ITR, CONT) for (auto ITR = begin(CONT); ITR != end(CONT); ITR++)
#define itrep1(ITR, CONT)                                                      \\
  for (auto ITR = next(begin(CONT)); ITR != end(CONT); ITR++)
template <typename T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
void prec(const int &DIG) {
  cerr << fixed << setprecision(DIG);
  cout << fixed << setprecision(DIG);
}
template <typename T> void CERR(const T &ELEM) { cerr << ELEM; }
template <typename T, typename... Ts>
void CERR(const T &FIRST, const Ts &...REST) {
  CERR(FIRST);
  cerr << ", ";
  CERR(REST...);
}
template <typename T1, typename T2> void CERR(const pair<T1, T2> &PAIR) {
  cerr << "(";
  CERR(PAIR.first);
  cerr << ", ";
  CERR(PAIR.second);
  cerr << ")";
}
template <typename T> void CERR(const vector<T> &VEC) {
  cerr << "{ ";
  itrep(ITR, VEC) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
template <typename T> void CERR1(const vector<T> &VEC) {
  cerr << "{ ";
  itrep1(ITR, VEC) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
template <typename T> void CERR(const set<T> &SET) {
  cerr << "{ ";
  itrep(ITR, SET) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
template <typename T> void CERR(const multiset<T> &MULTISET) {
  cerr << "{ ";
  itrep(ITR, MULTISET) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
template <typename T1, typename T2> void CERR(const map<T1, T2> &MAP) {
  cerr << "{ ";
  itrep(ITR, MAP) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
#define db(OBJ)                                                                \\
  cerr << #OBJ << ": ";                                                        \\
  CERR(OBJ);                                                                   \\
  cerr << ", "
#define dbl(OBJ)                                                               \\
  cerr << #OBJ << ": ";                                                        \\
  CERR(OBJ);                                                                   \\
  cerr << "\\n"
#define db1(OBJ)                                                               \\
  cerr << #OBJ << ": ";                                                        \\
  CERR1(OBJ);                                                                  \\
  cerr << "\\n"
#define dbs(...)                                                               \\
  cerr << "(" << #__VA_ARGS__ << "): (";                                       \\
  CERR(__VA_ARGS__);                                                           \\
  cerr << ")\\n"
#define dbvv(VV)                                                               \\
  cerr << #VV << ": {\\n";                                                      \\
  rep(CNT, VV.size()) {                                                        \\
    cerr << #VV << "[" << CNT << "]: ";                                        \\
    CERR(VV[CNT]);                                                             \\
    cerr << ",\\n";                                                             \\
  }                                                                            \\
  cerr << "}\\n"
#define db01(VV)                                                               \\
  cerr << #VV << ": {\\n";                                                      \\
  rep(CNT, VV.size()) {                                                        \\
    cerr << #VV << "[" << CNT << "]: ";                                        \\
    CERR1(VV[CNT]);                                                            \\
    cerr << ",\\n";                                                             \\
  }                                                                            \\
  cerr << "}\\n"
#define db10(VV)                                                               \\
  cerr << #VV << ": {\\n";                                                      \\
  rep2(CNT, 1, VV.size()) {                                                    \\
    cerr << #VV << "[" << CNT << "]: ";                                        \\
    CERR(VV[CNT]);                                                             \\
    cerr << ",\\n";                                                             \\
  }                                                                            \\
  cerr << "}\\n"
#define db11(VV)                                                               \\
  cerr << #VV << ": {\\n";                                                      \\
  rep2(CNT, 1, VV.size()) {                                                    \\
    cerr << #VV << "[" << CNT << "]: ";                                        \\
    CERR1(VV[CNT]);                                                            \\
    cerr << ",\\n";                                                             \\
  }                                                                            \\
  cerr << "}\\n"
#define YN(FLG) cout << (FLG ? "YES" : "NO") << "\\n"
#define Yn(FLG) cout << (FLG ? "Yes" : "No") << "\\n"
#define yn(FLG) cout << (FLG ? "yes" : "no") << "\\n"
// const ll INF = 1'000'000'000'000'000'007;
const int INF = 1'000'000'007;
const ll MOD = 1'000'000'007; // 998'244'353;

// [isPrime, Prime Factrozation, Number of Prime Factors]
pair<ll, int> divs(ll N, ll prm) {
  assert(N > 0);
  int deg = 0;
  for (; N % prm == 0; deg++)
    N /= prm;
  return pair<ll, int>(N, deg);
}
bool isprime(ll N) {
  assert(N > 0);
  if (N == 1)
    return false;
  for (int k = 2; k * k <= N; k++)
    if (N % k == 0)
      return false;
  return true;
}
map<ll, int> pf(ll N) {
  assert(N > 0);
  map<ll, int> res;
  for (ll prm = 2; prm * prm <= N; prm++)
    if (N % prm == 0)
      tie(N, res[prm]) = divs(N, prm);
  if (N > 1)
    res[N] = 1;
  return res;
}
int NPF(ll N) {
  assert(N > 0);
  int res = 0;
  for (pair<ll, int> p : pf(N))
    res += p.second;
  return res;
}

// [Number of Divisors, Sum of Divisors, Divisors]
ll npow(ll x, int n) {
  assert(n >= 0);
  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res *= x;
    x *= x;
    n >>= 1;
  }
  return res;
}
int ND(ll N) {
  assert(N > 0);
  int res = 1;
  for (pair<ll, int> p : pf(N))
    res *= (p.second + 1);
  return res;
}
ll SD(ll N) {
  assert(N > 0);
  ll res = 1;
  for (pair<ll, int> p : pf(N))
    res *= (npow(p.first, p.second + 1) - 1) / (p.first - 1);
  return res;
}
set<ll> divisors(ll N) {
  assert(N > 0);
  set<ll> res;
  queue<ll> q;
  q.push(1LL);
  res.insert(1LL);
  for (pair<ll, ll> p : pf(N)) {
    ll prm, deg;
    tie(prm, deg) = p;
    queue<ll> temp;
    while (!q.empty()) {
      ll x = q.front();
      q.pop();
      temp.push(x);
      rep0(deg) {
        x *= prm;
        temp.push(x);
        res.insert(x);
      }
    }
    q = temp;
  }
  return res;
}

// [Sieve of Eratosthenes]
set<int> SE(int N) {
  assert(N > 0);
  set<int> res;
  vector<bool> v(N + 1, true);
  v[0] = v[1] = false;
  int prm = 2;
  while (prm <= N) {
    res.insert(prm);
    for (int k = 2; k * prm <= N; k++)
      v[k * prm] = false;
    prm++;
    while (prm <= N and !v[prm])
      prm++;
  }
  return res;
}

int N;
vector<double> A;
vl k;
vi d;

map<pair<int, int>, ll> twos, fives;
map<int, ll> ones;

// A[i]を，10の倍数でない整数k[i]を用いてk[i]*10^d[i]の形で表す
// d[i]は-9以上3以下
// dごとに，素因数2の個数がjであるもの，素因数5の個数がkであるものの個数を数える

void check(int i) {
  k[i] = (ll)(A[i] * 1'000'000'000LL + 0.5);
  d[i] = -9;
  while (k[i] % 10 == 0) {
    k[i] /= 10;
    d[i]++;
  }

  if (k[i] % 2 == 0) {
    twos[make_pair(d[i], divs(k[i], 2).second)]++;
  } else if (k[i] % 5 == 0) {
    fives[make_pair(d[i], divs(k[i], 5).second)]++;
  } else {
    ones[d[i]]++;
  }
}

int main() {
  prec(9);
  cin >> N;
  A = vector<double>(N);
  rep(i, N) cin >> A[i];
  k = vl(N);
  d = vi(N);
  rep(i, N) check(i);
  // dbvv(A); dbl(twos); dbl(fives); dbl(ones);
  // rep(i, N) { dbs(i, k[i], d[i]); }

  ll ans = 0, temp = 0;

  // one * one
  temp = 0;
  for (pair<int, ll> p : ones) {
    for (pair<int, ll> q : ones) {
      if (p.first + q.first < 0)
        continue;
      // db(p); db(q);

      if (p.first == q.first) {
        temp += p.second * (q.second - 1);
      } else {
        temp += p.second * q.second;
      }
      // dbl(temp);
    }
  }
  // dbs("one*one", temp/2);
  ans += temp / 2;

  // one * two
  temp = 0;
  for (pair<int, ll> p : ones) {
    for (pair<pair<int, int>, ll> q : twos) {
      if (p.first + q.first.first < 0)
        continue;
      temp += p.second * q.second;
    }
  }
  // dbs("one*two", temp);
  ans += temp;

  // one * five
  temp = 0;
  for (pair<int, ll> p : ones) {
    for (pair<pair<int, int>, ll> q : fives) {
      if (p.first + q.first.first < 0)
        continue;
      temp += p.second * q.second;
    }
  }
  // dbs("one*five", temp);
  ans += temp;

  // two * two
  temp = 0;
  for (pair<pair<int, int>, ll> p : twos) {
    for (pair<pair<int, int>, ll> q : twos) {
      if (p.first.first + q.first.first < 0)
        continue;
      if (p.first == q.first) {
        temp += p.second * (q.second - 1);
      } else {
        temp += p.second * q.second;
      }
    }
  }
  // dbs("two*two", temp/2);
  ans += temp / 2;

  // five * five
  temp = 0;
  for (pair<pair<int, int>, ll> p : fives) {
    for (pair<pair<int, int>, ll> q : fives) {
      if (p.first.first + q.first.first < 0)
        continue;
      if (p.first == q.first) {
        temp += p.second * (q.second - 1);
      } else {
        temp += p.second * q.second;
      }
    }
  }
  // dbs("five*five", temp/2);
  ans += temp / 2;

  // two * five
  temp = 0;
  for (pair<pair<int, int>, ll> p : twos) {
    // dbl(p);
    for (pair<pair<int, int>, ll> q : fives) {
      // dbl(q);
      if (p.first.first + q.first.first + min(p.first.second, q.first.second) >=
          0) {
        temp += p.second * q.second;
      }
    }
  }
  // dbs("two*five", temp);
  ans += temp;

  cout << ans << endl;
}

Error: TLE

Fixed submission:

#define _GLIBCXX_DEBUG
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
#define rep0(TMS) for (int CNT = 0; CNT < (int)(TMS); CNT++)
#define rep(CNT, GOAL) for (int CNT = 0; CNT < (int)(GOAL); CNT++)
#define rep2(CNT, START, GOAL)                                                 \\
  for (int CNT = (int)(START); CNT < (int)(GOAL); CNT++)
#define rep3(CNT, START, GOAL)                                                 \\
  for (int CNT = (int)(START); CNT > (int)(GOAL); CNT--)
#define all(CONT) begin(CONT), end(CONT)
#define itrep(ITR, CONT) for (auto ITR = begin(CONT); ITR != end(CONT); ITR++)
#define itrep1(ITR, CONT)                                                      \\
  for (auto ITR = next(begin(CONT)); ITR != end(CONT); ITR++)
template <typename T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
void prec(const int &DIG) {
  cerr << fixed << setprecision(DIG);
  cout << fixed << setprecision(DIG);
}
template <typename T> void CERR(const T &ELEM) { cerr << ELEM; }
template <typename T, typename... Ts>
void CERR(const T &FIRST, const Ts &...REST) {
  CERR(FIRST);
  cerr << ", ";
  CERR(REST...);
}
template <typename T1, typename T2> void CERR(const pair<T1, T2> &PAIR) {
  cerr << "(";
  CERR(PAIR.first);
  cerr << ", ";
  CERR(PAIR.second);
  cerr << ")";
}
template <typename T> void CERR(const vector<T> &VEC) {
  cerr << "{ ";
  itrep(ITR, VEC) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
template <typename T> void CERR1(const vector<T> &VEC) {
  cerr << "{ ";
  itrep1(ITR, VEC) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
template <typename T> void CERR(const set<T> &SET) {
  cerr << "{ ";
  itrep(ITR, SET) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
template <typename T> void CERR(const multiset<T> &MULTISET) {
  cerr << "{ ";
  itrep(ITR, MULTISET) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
template <typename T1, typename T2> void CERR(const map<T1, T2> &MAP) {
  cerr << "{ ";
  itrep(ITR, MAP) {
    CERR(*ITR);
    cerr << ", ";
  }
  cerr << "}";
}
#define db(OBJ)                                                                \\
  cerr << #OBJ << ": ";                                                        \\
  CERR(OBJ);                                                                   \\
  cerr << ", "
#define dbl(OBJ)                                                               \\
  cerr << #OBJ << ": ";                                                        \\
  CERR(OBJ);                                                                   \\
  cerr << "\\n"
#define db1(OBJ)                                                               \\
  cerr << #OBJ << ": ";                                                        \\
  CERR1(OBJ);                                                                  \\
  cerr << "\\n"
#define dbs(...)                                                               \\
  cerr << "(" << #__VA_ARGS__ << "): (";                                       \\
  CERR(__VA_ARGS__);                                                           \\
  cerr << ")\\n"
#define dbvv(VV)                                                               \\
  cerr << #VV << ": {\\n";                                                      \\
  rep(CNT, VV.size()) {                                                        \\
    cerr << #VV << "[" << CNT << "]: ";                                        \\
    CERR(VV[CNT]);                                                             \\
    cerr << ",\\n";                                                             \\
  }                                                                            \\
  cerr << "}\\n"
#define db01(VV)                                                               \\
  cerr << #VV << ": {\\n";                                                      \\
  rep(CNT, VV.size()) {                                                        \\
    cerr << #VV << "[" << CNT << "]: ";                                        \\
    CERR1(VV[CNT]);                                                            \\
    cerr << ",\\n";                                                             \\
  }                                                                            \\
  cerr << "}\\n"
#define db10(VV)                                                               \\
  cerr << #VV << ": {\\n";                                                      \\
  rep2(CNT, 1, VV.size()) {                                                    \\
    cerr << #VV << "[" << CNT << "]: ";                                        \\
    CERR(VV[CNT]);                                                             \\
    cerr << ",\\n";                                                             \\
  }                                                                            \\
  cerr << "}\\n"
#define db11(VV)                                                               \\
  cerr << #VV << ": {\\n";                                                      \\
  rep2(CNT, 1, VV.size()) {                                                    \\
    cerr << #VV << "[" << CNT << "]: ";                                        \\
    CERR1(VV[CNT]);                                                            \\
    cerr << ",\\n";                                                             \\
  }                                                                            \\
  cerr << "}\\n"
#define YN(FLG) cout << (FLG ? "YES" : "NO") << "\\n"
#define Yn(FLG) cout << (FLG ? "Yes" : "No") << "\\n"
#define yn(FLG) cout << (FLG ? "yes" : "no") << "\\n"
// const ll INF = 1'000'000'000'000'000'007;
const int INF = 1'000'000'007;
const ll MOD = 1'000'000'007; // 998'244'353;

// [isPrime, Prime Factrozation, Number of Prime Factors]
pair<ll, int> divs(ll N, ll prm) {
  assert(N > 0);
  int deg = 0;
  for (; N % prm == 0; deg++)
    N /= prm;
  return pair<ll, int>(N, deg);
}
bool isprime(ll N) {
  assert(N > 0);
  if (N == 1)
    return false;
  for (int k = 2; k * k <= N; k++)
    if (N % k == 0)
      return false;
  return true;
}
map<ll, int> pf(ll N) {
  assert(N > 0);
  map<ll, int> res;
  for (ll prm = 2; prm * prm <= N; prm++)
    if (N % prm == 0)
      tie(N, res[prm]) = divs(N, prm);
  if (N > 1)
    res[N] = 1;
  return res;
}
int NPF(ll N) {
  assert(N > 0);
  int res = 0;
  for (pair<ll, int> p : pf(N))
    res += p.second;
  return res;
}

// [Number of Divisors, Sum of Divisors, Divisors]
ll npow(ll x, int n) {
  assert(n >= 0);
  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res *= x;
    x *= x;
    n >>= 1;
  }
  return res;
}
int ND(ll N) {
  assert(N > 0);
  int res = 1;
  for (pair<ll, int> p : pf(N))
    res *= (p.second + 1);
  return res;
}
ll SD(ll N) {
  assert(N > 0);
  ll res = 1;
  for (pair<ll, int> p : pf(N))
    res *= (npow(p.first, p.second + 1) - 1) / (p.first - 1);
  return res;
}
set<ll> divisors(ll N) {
  assert(N > 0);
  set<ll> res;
  queue<ll> q;
  q.push(1LL);
  res.insert(1LL);
  for (pair<ll, ll> p : pf(N)) {
    ll prm, deg;
    tie(prm, deg) = p;
    queue<ll> temp;
    while (!q.empty()) {
      ll x = q.front();
      q.pop();
      temp.push(x);
      rep0(deg) {
        x *= prm;
        temp.push(x);
        res.insert(x);
      }
    }
    q = temp;
  }
  return res;
}

// [Sieve of Eratosthenes]
set<int> SE(int N) {
  assert(N > 0);
  set<int> res;
  vector<bool> v(N + 1, true);
  v[0] = v[1] = false;
  int prm = 2;
  while (prm <= N) {
    res.insert(prm);
    for (int k = 2; k * prm <= N; k++)
      v[k * prm] = false;
    prm++;
    while (prm <= N and !v[prm])
      prm++;
  }
  return res;
}

int N;
vector<double> A;
vl num, den;
map<ll, set<int>> num2i, den2i;
// vector<pair<ll, int>> num2i, den2i;

int main() {
  cin >> N;
  A = vector<double>(N);
  rep(i, N) cin >> A[i];
  num = den = vl(N);
  rep(i, N) {
    ll g = __gcd((ll)(A[i] * 1'000'000'000 + 0.5), 1'000'000'000LL);
    num[i] = (ll)(A[i] * 1'000'000'000 + 0.5) / g;
    den[i] = 1'000'000'000 / g;

    num2i[num[i]].insert(i);
    den2i[den[i]].insert(i);
  }

  // dbvv(A);
  // dbvv(num); dbvv(den);
  // dbvv(num2i); dbvv(den2i);

  ll ans = 0;
  rep(i, N) {
    // dbs(num[i], den[i]);
    // dbl(divisors(num[i]));
    for (ll p : divisors(num[i])) {
      // dbl(p);
      // 分子num[i]の約数pを分母に持つものがあるか?
      if (!den2i.count(p))
        continue;
      // dbl(den2i[p]);
      for (int j : den2i[p]) {
        if (j <= i)
          continue;

        // もし分母den[j]がpを約数に持つならば，
        // 分子num[j]は分母den[i]を割り切るか?
        if (num[j] % den[i] == 0) {
          ans++;
          // cerr << "OK" << endl;
        }
      }
    }
  }

  cout << ans << endl;
}