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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<int, pair<int, int>> piii;
typedef vector<int> vi;
typedef vector<pii> vii;

#define ri(a) scanf("%d", &a)
#define rii(a, b) scanf("%d %d", &a, &b)
#define riii(a, b, c) scanf("%d %d %d", &a, &b, &c)
#define rl(a) scanf("%lld", &a)
#define rll(a, b) scanf("%lld %lld", &a, &b)
#define FOR(i, n, m) for (int i = n; i < m; i++)
#define ROF(i, n, m) for (int i = n; i > m; i--)
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define F first
#define S second

const int INF = 0x3f3f3f3f;
const ll LLINF = 1e18;
const int maxN = 2e5; // CAMBIAR ESTE

// GJNM
ll cnt[60][60]; //?

int main() {
  int n;
  ri(n);
  ll DEN = 1e9;
  FOR(i, 0, n) {
    long double aux;
    scanf("%Lf", &aux);
    ll val = round(DEN * aux);
    int five = 0, two = 0;
    while (val % 2 == 0) {
      two++;
      val /= 2;
    }
    while (val % 5 == 0) {
      five++;
      val /= 5;
    }
    cnt[two][five]++;
  }
  ll ans = 0;
  FOR(i, 0, 60) {
    FOR(j, 0, 60) {
      FOR(ii, 0, 60) {
        FOR(jj, 0, 60) {
          if (make_pair(i, j) > make_pair(ii, jj))
            continue;
          if (i + ii >= 18 && j + jj >= 18) {
            if (i == ii && j == jj) {
              ans += (cnt[i][j] * (cnt[ii][jj] - 1ll)) / 2ll;
            } else {
              ans += (cnt[i][j] * cnt[ii][jj]);
            }
          }
        }
      }
    }
  }
  printf("%lld\\n", ans);
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<int, pair<int, int>> piii;
typedef vector<int> vi;
typedef vector<pii> vii;

#define ri(a) scanf("%d", &a)
#define rii(a, b) scanf("%d %d", &a, &b)
#define riii(a, b, c) scanf("%d %d %d", &a, &b, &c)
#define rl(a) scanf("%lld", &a)
#define rll(a, b) scanf("%lld %lld", &a, &b)
#define FOR(i, n, m) for (int i = n; i < m; i++)
#define ROF(i, n, m) for (int i = n; i > m; i--)
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define F first
#define S second

const int INF = 0x3f3f3f3f;
const ll LLINF = 1e18;
const int maxN = 2e5; // CAMBIAR ESTE

// GJNM
ll MAX_D;
ll MIN_D = LLINF;
int n;
ll NUM[maxN], DEN[maxN];
char s[20];
map<pair<ll, ll>, ll> cnt;
map<pair<ll, ll>, ll> cnt2;
pair<ll, ll> ND[maxN];

int main() {
  ri(n);
  FOR(i, 0, n) {
    scanf("%s", s);
    int j = 0;
    ll aux = 0;
    int point = -1;
    while (s[j] != '\\0') {
      if (s[j] == '.') {
        point = j;
        j++;
        continue;
      }
      aux *= 10;
      aux += (s[j] - '0');
      j++;
    }

    if (point == -1) {
      NUM[i] = aux;
      DEN[i] = 1;
    } else {
      NUM[i] = aux;
      DEN[i] = 1;
      FOR(k, point, j - 1) { DEN[i] *= 10ll; }
    }
    ll gcdd = __gcd(NUM[i], DEN[i]);
    NUM[i] /= gcdd;
    DEN[i] /= gcdd;
    MAX_D = max(MAX_D, DEN[i]);
    MIN_D = min(MIN_D, DEN[i]);
    ND[i] = {NUM[i], DEN[i]};
    cnt2[{NUM[i], DEN[i]}]++;
  }
  sort(ND, ND + n);
  FOR(i, 0, n) {
    NUM[i] = ND[i].F;
    DEN[i] = ND[i].S;
  }

  ll ans = 0;
  ll last_ans;
  FOR(i, 0, n) {
    if (i > 0) {
      if (ND[i] == ND[i - 1]) {
        if (DEN[i] == 1)
          last_ans++;
        ans += last_ans;
        continue;
      }
    }

    last_ans = ans;
    for (ll j = MIN_D; j * j <= min(NUM[i], MAX_D * MAX_D); ++j) {
      if (NUM[i] % j == 0) {
        ans += cnt[{DEN[i], j}];
        cnt[{j, DEN[i]}] += cnt2[{NUM[i], DEN[i]}];
        if (NUM[i] / j != j) {
          ans += cnt[{DEN[i], NUM[i] / j}];
          cnt[{NUM[i] / j, DEN[i]}] += cnt2[{NUM[i], DEN[i]}];
        }
      }
    }
    last_ans = ans - last_ans;
  }
  printf("%lld\\n", ans);

  return 0;
}