Cod sursa(job #119800)

Utilizator Binary_FireFlorin Pg Binary_Fire Data 3 ianuarie 2008 12:45:05
Problema Pairs Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.38 kb
#include <cstdio>

#define fin  "pairs.in"
#define fout "pairs.out"

const int Nmax = 100100;
const int Vmax = 1000100;

int N,maxv,v[Nmax];
int a[Vmax],npr[1000];;
int diviz[10];

long long cnt1,cnt2;

void readdata()
{
	int i;

	freopen(fin,"r",stdin);
	
	scanf("%d",&N);

	for (i=1;i<=N;++i)
	{
		scanf("%d",&v[i]);	
		a[v[i]]=1;
		if ( v[i] > maxv )
			maxv = v[i];
	}
}

void preproc()
{
	int i,j;

	for (i=2;i<=maxv;++i)
	for (j=i+i;j<=maxv;j+=i)
		a[i]+=a[j];

	for (i=2;i<1000;++i)
	{
		for (j=1;j<=npr[0];++j)
			if (i%npr[j]==0)
				break;
		if (j>npr[0])
			npr[++npr[0]]=i;
	}
}

void descompune(int nr)
{
	int j,bun;

	diviz[0]=0;

	for (j=1;npr[j]*npr[j] <= nr;++j)
	{
		bun=0;
		while (nr % npr[j] == 0)
		{
			bun=1;
			nr/=npr[j];
		}
		if (bun)
			diviz[++diviz[0]]=npr[j];
	}

	if (nr>1)
		diviz[++diviz[0]]=nr;
}

void go(int lev,int last,int prod)
{
	int i;

	if ( lev > 0 )
	{
		if ( lev % 2 == 0 )
			cnt2 -= ( a[prod] - 1 );
		else
			cnt2 += ( a[prod] - 1 );
	}

	if ( lev == diviz[0] )
		return ;

	for (i=last+1;i<=diviz[0];++i)
		go(lev+1,i,prod*diviz[i]);
}

void solve()
{
	int i;

	preproc();

	cnt1 = N-1;
	cnt1 = cnt1 * N;
	cnt1 = cnt1 / 2;

	cnt2 = 0;

	for (i=1;i<=N;++i)
	{
		descompune(v[i]);
		go(0,0,1);
	}

	cnt2/=2;

	cnt1 -= cnt2;
}

void printdata()
{
	freopen(fout,"w",stdout);

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

int main()
{
	readdata();
	solve();
	printdata();
	return 0;
}