Cod sursa(job #2501215)

Utilizator Iulia25Hosu Iulia Iulia25 Data 29 noiembrie 2019 11:28:27
Problema Pairs Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.6 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream fin ("pairs.in");
ofstream fout ("pairs.out");

int n, nr;
int a[100005], v[1005], NR[1000005];
bool m[1000005];

vector <int> c[100005];

int cmmdc(int x, int y)	 {
	int r = x % y;
	while (r)	 {
		x = y;
		y = r;
		r = x % y;
	}
	return y;
}

int brut()	{
	int ans = 0;
	for (int i = 1; i <= n; ++i)	{
		for (int j = i + 1; j <= n; ++j)	{
			if (a[i] != a[j] && cmmdc(a[i], a[j]) == 1)
				++ans;
		}
	}
	return ans;
}

long long pinex(int x)	{
	long long ans = n - x;
	int lim = 1 << (c[x].size());
	for (int j = 1; j < lim; ++j)	 {
		int div = 1, nr1 = 0;
		for (int s = j, k = 0; s; s >>= 1, ++k)	{
			if (s & 1)
				div *= c[x][k], ++nr1;
		}
		--NR[div];
		if (nr1 & 1)
			ans -= NR[div];
		else
			ans += NR[div];
	}
	return ans;
}

long long solve()	{
	for (int i = 4; i <= 1000000; i += 2)	{
		m[i] = true;
	}
	v[++nr] = 2;
	for (int i = 3; i * i <= 1000000; i += 2)	 {
		if (!m[i])	{
			v[++nr] = i;
			for (int j = i * i; j <= 1000000; j += i)
				m[j] = true;
		}
	}
	for (int i = 1; i <= n; ++i)	{
		for (int j = 1; j <= nr; ++j)	 {
			if (a[i] % v[j] == 0)	{
				c[i].push_back(v[j]);
			}
		}
		int lim = 1 << (c[i].size());
		for (int j = 1; j < lim; ++j)	 {
			int div = 1;
			for (int s = j, k = 0; s; s >>= 1, ++k)	{
				if (s & 1)
					div *= c[i][k];
			}
			++NR[div];
		}
	}
	long long ans = 0;
	for (int i = 1; i <= n; ++i)	{
		ans += pinex(i);
	}
	return ans;
}

int main()	{
	fin >> n;;
	for (int i = 1; i <= n; ++i)
		fin >> a[i];
	if (n <= 1000)	{
		fout << brut();
		return 0;
	}
	long long ans = 0;
	ans = solve();
	fout << ans;
	return 0;
}