Cod sursa(job #109861)

Utilizator victorsbVictor Rusu victorsb Data 25 noiembrie 2007 12:51:16
Problema Pairs Scor 100
Compilator cpp Status done
Runda preONI 2008, Runda 1, Clasa a 10-a Marime 1.24 kb
#include <cstdio>
#include <cmath>

#define Nmax 100015
#define Pmax 256
#define Vmax 1000015
#define ll long long

int n, ct;
int sir[Nmax];
int prim[Pmax];
int p[8];
ll nr[Vmax];

void citire()
{
	int i;

	scanf("%d\n", &n);
	for (i = 1; i <= n; ++i)
		scanf("%d\n", &sir[i]);
}

int pr(int n)
{
	int i, rad = (int)(sqrt(n));

	for (i = 2; i <= rad; ++i)
		if (n % i == 0) return 0;
	return 1;
}

void solve()
{
	int i, j, m, mask, div, sgn;
	ll sol = 0;

	for (i = 2; i <= 1000; ++i)
		if (pr(i))
			prim[++ct] = i;

	for (i = 1; i <= n; ++i)
	{
		m = 0;
		for (j = 1; j <= ct; ++j)
			if (sir[i] % prim[j] == 0)
			{
				p[++m] = prim[j];
				while (sir[i] % prim[j] == 0)
					sir[i] /= prim[j];
			}
		if (sir[i] != 1) p[++m] = sir[i];

        sol += i - 1;
		for (mask = 1; mask < 1 << m; ++mask)
		{
			div = 1;
			sgn = 1;
			for (j = 0; j < m; ++j)
				if ((mask >> j) & 1)
				{
					sgn = -sgn;
					div *= p[j + 1];
				}

			sol += sgn * nr[div];
		}

		for (mask = 1; mask < 1 << m; ++mask)
		{
			div = 1;
			for (j = 0; j < m; ++j)
				if ((mask >> j) & 1)
					div *= p[j + 1];
			++nr[div];
		}
	}

	printf("%lld\n", sol);
}

int main()
{
	freopen("pairs.in", "r", stdin);
	freopen("pairs.out", "w", stdout);

	citire();
	solve();

	return 0;
}