Cod sursa(job #124554)

Utilizator azotlichidAdrian Vladu azotlichid Data 19 ianuarie 2008 15:56:29
Problema Pairs Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <cstring>
using namespace std;

#define ALL(x) (x).begin(), (x).end()
#define CLEAR(X) (memset(X, 0, sizeof(X)))
#define FORI(it, x) for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); ++it)
#define FOR(i, N, M) for (int i = (int)(N); i <= (int)(M); ++i)
#define REP(i, N) for (int i = 0; i < (int)(N); ++i)
#define SIZE(X) (int)((X).size())
#define TIPA(a, i) (cerr << #a << "[" #i " = " << (i) << "] = " << (a)[i] << endl)
#define TIP(x) (cerr << #x << " = " << (x) << endl)

#define MP make_pair
#define PB push_back
#define INF 0x3F3F3F3F

typedef long long LL;

#define NMAX 100005
#define FMAX 20
#define VMAX 1000005

int N, x, k, a[NMAX], nr[VMAX], f[FMAX];

void factor(int x)
{
	k = 0;
	for (int i = 2; i*i <= x; i++)
		if (x%i == 0)
		{
			f[k++] = i;
			while (x%i == 0) x /= i;
		}
	if (x > 1)
		f[k++] = x;
}

void baga(int x)
{
	factor(x);
	
	FOR(stp, 1, (1<<k)-1)
	{
		int prod = 1;
		REP(p, k)
			if ((stp>>p)&1)
				prod *= f[p];
		++nr[prod];
	}
}

int scoate(int x)
{
	int ret = N;
	factor(x);
	
	FOR(stp, 1, (1<<k)-1)
	{
		int prod = 1, cnt = 0;
		REP(p, k)
			if ((stp>>p)&1)
				prod *= f[p], ++cnt;
		if (cnt&1)
			ret -= nr[prod];
		else
			ret += nr[prod];
	}
	return ret;
}

int gcd(int a, int b)
{
	int c;
	do { c = a % b, a = b, b = c; } while (c != 0);
	return a;
}

void brute(void)
{
	int ret = 0;
	REP(i, N)
		FOR(j, i+1, N-1)
			if (gcd(a[i], a[j]) == 1)
				++ ret;
	printf("brute >> %d\n", ret);
}


void gen(void)
{
	freopen("pairs.in", "w", stdout);
	N = 10000;
	printf("%d\n", N);
	REP(i, N)
		printf("%d\n", 1+rand() % 1000000);
}

int main(void)
{
    freopen("pairs.in", "r", stdin);
    freopen("pairs.out", "w", stdout);
	scanf("%d", &N);

	memset(nr, 0, sizeof(nr));
	REP(i, N)
	{
		scanf("%d", &x);
		a[i] = x;
		baga(x);
	}

	int Ans = 0;
	REP(i, N)
		Ans += scoate(a[i]);
	printf("%d\n", Ans/2);

    return 0;
}