Cod sursa(job #226836)

Utilizator CezarMocanCezar Mocan CezarMocan Data 2 decembrie 2008 21:45:25
Problema Pairs Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.36 kb
#include <cstdio>
#include <vector>

using namespace std;

int n, i, j, nrd[1000000], st[17], v, nrf[100100];

int fact[100100][17];

long long r, tot;

void desc(int n) {
	int d;
	for (d = 1; d * d <= n; d++) {
		if (n % d == 0) {
			nrd[d]++;
			if (d != (n / d))
				nrd[n / d]++;
		}
	}
	
	if (n % 2 == 0) {
		nrf[i]++;
		fact[i][nrf[i]] = 2;
		while (n % 2 == 0) 
			n /= 2;
	}
	for (d = 3; d * d <= n && n > 1; d += 2) {
		if (n % d == 0) {
			nrf[i]++;
			fact[i][nrf[i]] = d;
			while (n % d == 0)
				n /= d;
		}
	}
	
	if (n > 1) {
		nrf[i]++;
		fact[i][nrf[i]] = n;
	}
}

int barbut(int n) {
	memset(st, 0, sizeof(st));
	int i, j, nr1, sum = 0, pr;
	
	for (i = 0; i < (1 << nrf[n]); i++) {
		pr = 1; nr1 = 0;
		for (j = 1; j <= nrf[n]; j++) {
			pr *= st[j] * fact[n][j];
			nr1+= st[j];
		}		
		if (nrd[pr])
			if (nr1 & 1)
				sum += (nrd[pr] - 1);
			else
				sum -= (nrd[pr] - 1);
		
		j = nrf[n];
		while (st[j] == 1 && j) {
			st[j] = 0;
			j--;
		}
		st[j] = 1;
	}
	
	return sum;
}

int main() {
	freopen("pairs.in", "r", stdin);
	freopen("pairs.out", "w", stdout);
	
	scanf("%d", &n);
	
	tot = (1LL * n * (n - 1));
	
	for (i = 1; i <= n; i++) {
		scanf("%d", &v);
		desc(v);
	}
	nrd[1] = 0;
	
	for (i = 1; i <= n; i++) 
		tot -= barbut(i);
	
	printf("%lld\n", tot / 2);
	
	return 0;
}