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: Accepted)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

long long gcd(long long a, long long b) {
	if (a == 0 || b == 0) {
		return a + b;
	}
	if (a > b) {
		return gcd(a % b, b);
	}
	return gcd(a, b % a);
}

pair<long long, long long> parse(string s) {
	int ps = -1;
	for (int i = 0; i < s.length(); ++i) {
		if (s[i] == '.') {
			ps = i;
		}
	}
	if (ps == -1) {
		s += '.';
		ps = s.length() - 1;
	}

	int len = (int)(s.length()) - ps - 1;
	while (len < 9) {
		s += '0';
		++len;
	}

	long long val1 = 0;
	for (int i = 0; i < s.length(); ++i) {
		if (s[i] != '.') {
			val1 *= 10;
			val1 += s[i] - '0';
		}
	}
	long long val2 = 1000000000;

	long long d = gcd(val1, val2);
	val1 /= d;
	val2 /= d;
	return make_pair(val1, val2);
}

void solve() {
	int n;
	cin >> n;
	vector<pair<long long, long long> > v;

	int num = 1e9;

	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;

		v.push_back(parse(s));
	}

	vector<int> tot;
	for (int i = 1; i * i <= num; ++i) {
		if (num % i == 0) {
			tot.push_back(i);
			tot.push_back(num / i);
		}
	}

	vector<vector<int> > cmp(n, vector<int>(tot.size(), 0));
	vector<vector<int> > totals(tot.size());

	for (int i = 0; i < v.size(); ++i) {
		long long p = v[i].first;
		for (int j = 0; j < tot.size(); ++j) {
			if (p % tot[j] == 0) {
				++cmp[i][j];
			}
			if (v[i].second == tot[j]) {
				totals[j].push_back(i);
			}
		}
	}

	vector<vector<int> > res(tot.size(), vector<int>(tot.size(), 0));

	for (int i = 0; i < totals.size(); ++i) {
		vector<int> curcnt(tot.size(), 0);
		for (int j = 0; j < totals[i].size(); ++j) {
			int v = totals[i][j];
			for (int k = 0; k < tot.size(); ++k) {
				//if (k != i) {
					res[i][k] += cmp[v][k];
				//}
			}
		}
	}

	long long ans = 0;
	for (int i = 0; i < v.size(); ++i) {
		int idx = -1;
		for (int j = 0; j < tot.size(); ++j) {
			if (tot[j] == v[i].second) {
				idx = j;
			}
		}
		for (int j = 0; j < tot.size(); ++j) {
			if (cmp[i][j]) {
				if (idx == 0 && j == 0) {
					ans += res[j][idx] - 1;
				} else {
					ans += res[j][idx];
				}
			}
		}
	}
	cout << ans / 2 << endl;

	/*int res2 = 0;
	for (int i = 0; i < v.size(); ++i) {
		for (int j = i + 1; j < v.size(); ++j) {
			if (v[i].first % v[j].second == 0 && v[j].first % v[i].second == 0) {
				++res2;
			}
		}
	}
	cout << res2 << endl;*/
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(false);

	int t;
	//cin >> t;
	t = 1;

	for (int tt = 0; tt < t; ++tt) {
		solve();
	}


	return 0;
}