Cod sursa(job #109817)

Utilizator MariusMarius Stroe Marius Data 25 noiembrie 2007 12:45:23
Problema Pairs Scor 100
Compilator cpp Status done
Runda preONI 2008, Runda 1, Clasele 11-12 Marime 1.3 kb
#include <stdio.h>

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

#define MAX_N  100005
#define MAX_V  1000005

int Cnt[MAX_V], D[MAX_N][10];


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 X;
	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);
		
		getList(D[i], X);

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

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

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

	return 0;
}