Cod sursa(job #109746)

Utilizator MariusMarius Stroe Marius Data 25 noiembrie 2007 12:36:03
Problema Pairs Scor 0
Compilator cpp Status done
Runda preONI 2008, Runda 1, Clasa a 10-a Marime 1.32 kb
#include <stdio.h>

const char iname[] = "pairs.in";
const char oname[] = "pairs.out";

#define MAX_N  100005
#define MAX_V  1000005

int X[MAX_N], Cnt[MAX_V];


void getList(int L[], int n)
{
	if ((n & 1) == 0) {
		L[++ L[0]] = 2;
		while ((n & 1) == 0)
			n >>= 1;
	}
	for (int k = 3; k * k <= n; k += 2)
		if (n % k == 0) {
			L[++ L[0]] = k;
			while (n % k == 0)
				n /= k;
		}
	if (n > 1)
		L[++ L[0]] = n;
}

int main(void)
{
	int n;
	int L[10], size, upperlimit, cntr, p, i, j, sign;
	
	long long cnt, tcnt;

	FILE *fi = fopen(iname, "r");

	fscanf(fi, "%d\n", &n);
	for (i = 0; i < n; ++ i) {
		fscanf(fi, "%d\n", &X[i]);
		
		L[0] = 0, getList(L, X[i]);

		size = L[0];
		upperlimit = 1 << L[0];
		for (cntr = 1; cntr < upperlimit; cntr ++) {
			p = 1;
			for (j = 0; j < size; ++ j) if ((cntr >> j) & 1) 
				p = p * (L[j + 1]);
			Cnt[p] ++;
		}
	}
	fclose(fi);

	cnt = 0;
	for (int i = 0; i < n; ++ i) {
		L[0] = 0, getList(L, X[i]);

		size = L[0];
		upperlimit = 1 << L[0];
		tcnt = 0;
		for (cntr = 1; cntr < upperlimit; cntr ++) {
			sign = -1;
			p = 1;
			for (j = 0; j < size; ++ j) if ((cntr >> j) & 1) {
				p = p * (L[j + 1]);
				sign *= -1;
			}
			tcnt += (long long)sign * Cnt[p];
		}
		cnt += tcnt - 1;
	}
	
	FILE *fo = fopen(oname, "w");

	fprintf("%lld\n", ((long long)n)*(n-1)/2 - cnt/2);
	fclose(fo);

	return 0;
}