Cod sursa(job #264498)

Utilizator CezarMocanCezar Mocan CezarMocan Data 22 februarie 2009 11:07:33
Problema Pairs Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.73 kb
#include <cstdio>
#include <vector>

using namespace std;

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

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;
	}
}

inline 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++) 
			if (st[j] == 1) {
				pr *= fact[n][j];
				nr1++;
			}		
		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;
}

void barbut2(int k, int n) {
	int i;
	
	if (k == nrf[n]) {
		if (nrd[pr])
			if (nr1 & 1)
				sum += (nrd[pr] - 1);
			else
				sum -= (nrd[pr] - 1);
	}
	else {
		for (i = 0; i <= 1; i++) {
			st[k + 1] = i;
			if (i == 1) {
				pr *= fact[n][k + 1];
				nr1++;
				barbut2(k + 1, n);
				pr /= fact[n][k + 1];
				nr1--;
			}
			else
				barbut2(k + 1, n);
		}
	}
}

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++) {
		pr = 1;
		sum = nr1 = 0;
		barbut2(0, i);
		tot -= sum;
	}
	
	printf("%lld\n", tot / 2);
	
	return 0;
}