Cod sursa(job #920911)

Utilizator vld7Campeanu Vlad vld7 Data 20 martie 2013 17:58:04
Problema Pairs Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <fstream>

using namespace std;

ifstream f("pairs.in");
ofstream g("pairs.out");

const int MAX_N = 100005;
const int MAX_VAL = 1000000;

int n, a[MAX_N], prime[MAX_VAL], nrprimes, rez;
int X[MAX_VAL];		// X[i] = cate numere din M sunt divizibile cu i
bool frecv[MAX_VAL], prim[MAX_VAL + 5];

void ciur() {
	for (int i = 2; i <= MAX_VAL; i++)
		prim[i] = 1;
	
	for (int i = 2; i * i <= MAX_VAL; i++)
		if (prim[i]) {
			for (int j = i * i; j <= MAX_VAL; j += i)
				prim[j] = 0;
		}
		
	for (int i = 2; i <= MAX_VAL; i++)
		if (prim[i])
			prime[++nrprimes] = i;
}

void read() {
	f >> n;
	for (int i = 1; i <= n; i++) {
		f >> a[i];
		frecv[a[i]] = 1;
	}
}

void precompute() {
	for (int i = 2; i <= MAX_VAL; i++) {
		for (int j = i; j <= MAX_VAL; j += i)
			if (frecv[j])
				X[i]++;
		}
}

void solve() {
	for (int i = 2; i <= MAX_VAL; i++) {	// iau fiecare posibil divizor comun
		int j = i, ind = 1, ok = 1;
		int cnt = 0;	// cnt = cate numere prime au ca produs i
		// daca e par scad pentru ca s-au mai numarat perechile
		// daca e impar adun, s-a scazut prea mult
		
		if (X[i]) {
			while (j > 1) {
				if (j % prime[ind] == 0) {
					j /= prime[ind];
					cnt++;
					if (j % prime[ind] == 0) {
						ok = 0;
						j = 1;
					}
				}
				
				if (prime[ind] * prime[ind] > j && j > 1) {
					cnt++;
					j = 1;
				}
				
				ind++;
			}
			
			if (ok) {
				if (cnt % 2 == 0)
					cnt = -1;
				else
					cnt = 1;
				rez = rez + cnt * X[i] * (X[i] - 1) / 2;
			}
		}
	}
	
	rez = n * (n - 1) / 2 - rez;
}
	
int main() {
	ciur();
	read();
	precompute();
	solve();
	
	g << rez << '\n';
	
	f.close();
	g.close();
	
	return 0;
}