Problem:
Score : 300 points

Problem Statement

You are given N real values A_1, A_2, \ldots, A_N.
Compute the number of pairs of indices (i, j)
such that i < j and the product A_i \cdot A_j is integer.

Constraints

2 \leq N \leq 200\,000

0 < A_i < 10^4

A_i is given with at most 9 digits after the decimal.

Input

Input is given from Standard Input in the following format.

N
A_1
A_2
\vdots
A_N

Output

Print the number of pairs with integer product A_i \cdot A_j (and i < j).

Sample Input 1

5
7.5
2.4
17.000000001
17
16.000000000

Sample Output 1

3

There are 3 pairs with integer product:

7.5 \cdot 2.4 = 18

7.5 \cdot 16 = 120

17 \cdot 16 = 272

Sample Input 2

11
0.9
1
1
1.25
2.30000
5
70
0.000000001
9999.999999999
0.999999999
1.000000001

Sample Output 2

8

Solution in C++ (GCC 9.2.1) (judge verdict: Time Limit Exceeded)

#include "bits/stdc++.h"
using namespace std;

// 定義
typedef long long         ll;
typedef pair<ll, ll>      P;
#define ALL(x)            (x).begin(),(x).end()
#define REP(i, n)         for(ll i = 0 ; i < (ll)n ; ++i)
#define REPN(i, m, n)     for(ll i = m ; i < (ll)n ; ++i)
#define REVREP(i, n)      for(ll i = n - 1; i >= 0 ; i--)
#define VL                vector<ll>
#define VVL               vector<vector<ll>>
#define VVVL              vector<vector<vector<ll>>>
#define VC                vector<char>
#define VVC               vector<vector<char>>
#define INF               (ll)2e9
#define INF_LL            1LL<<60
//#define MOD             998244353
#define MOD               1000000007

ll Ceil(ll val, ll div)   { return (val + div - 1) / div; }
ll CeilN(ll val, ll div)  { return Ceil(val, div) * div; }
ll FloorN(ll x, ll n)     { return (x - x % n); }
bool IsOdd(ll x)          { return ((x & 1) == 1); }
bool IsEven(ll x)         { return ((x & 1) == 0); }
template<class T> bool chmax(T& a, T b) { if (a <= b) { a = b; return 1; } return 0; }
template<class T> bool chmin(T& a, T b) { if (a >= b) { a = b; return 1; } return 0; }

/* 素因数分解 */
map<ll, ll> primeFactor(ll n)
{
	map<ll, ll> factMap;

	if ((n % 2) == 0){
		while ((n % 2) == 0) {
			factMap[2]++;
			n = n / 2;
		}
	}

	for (ll i = 3; i <= sqrt(n); i += 2){
		while ((n % i) == 0){
			factMap[i]++;
			n = n / i;
		}
	}

	if (n != 1) {
		factMap[n]++;
	}

	return factMap;
}

/* baseのべき乗を求める */
template<class T>
T getPower(int exponet, int base)
{
	T ans = 1;
	for (int i = 0; i < exponet; i++) {
		ans *= base;
	}
	return ans;
}

void Solve()
{
	ll N;
	cin >> N;
	vector<string> A(N);
	REP(i, N) cin >> A[i];

	vector<P> primePair(N);

	auto getSosuuPari = [](ll val) {
		map<ll, ll> mp = primeFactor(val);
		P res = {mp[2], mp[5]};
		return res;
	};

	REP(i, N) {
		auto one = A[i];
		auto pos = one.find('.');
		
		ll topVal;
		ll divVal;
		if (pos == string::npos) {
			divVal = 1;
			topVal = stoll(one);
		} else {
			ll strLen = one.size() - pos - 1;
			string join = one.substr(0, pos) + one.substr(pos + 1);
			divVal = getPower<ll>(strLen, 10);
			topVal = stoll(join.c_str());
		}

		P topPrime = getSosuuPari(topVal);
		P divPrime = getSosuuPari(divVal);
		primePair[i].first = topPrime.first - divPrime.first;
		primePair[i].second = topPrime.second - divPrime.second;
	}

	ll geta = 20;
	VVL matrix(40, VL(40, 0));
	for (auto one : primePair) {
		matrix[one.first + geta][one.second + geta]++;
	}

	ll ans = 0;
	REP(idx, N) {
		auto one = primePair[idx];
		ll fstMin = (one.first * -1) + geta;
		ll secMin = (one.second * -1) + geta;
		REPN(i, fstMin, 40) {
			REPN(j, secMin, 40) {
				ans += matrix[i][j];
			}
		}
		if (0 <= one.first && 0 <= one.second) ans--;
	}

	cout << ans / 2 << endl;
}

// メイン
int main()
{
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(15);
	Solve();
	return 0;
}