Cod sursa(job #109400)

Utilizator damaDamaschin Mihai dama Data 25 noiembrie 2007 10:45:38
Problema Pairs Scor 100
Compilator cpp Status done
Runda preONI 2008, Runda 1, Clasele 11-12 Marime 1.76 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

int v[1024], prime[256], temp[16];
int d[1000001], nr = 1, cnt, bktprimes[100000];
long long sol;
bool used[1000001];

void ciur();
void finddiv(int);
void bkt(int);

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

	int i, a, ta, n, j;

	ciur();

	scanf("%d", &n);

	for(i = 1; i <= n; ++i)
	{
		memset(temp, 0, sizeof(temp));
		scanf("%d", &a);
		ta = a;
		for(j = 1; prime[j] * prime[j] <= a && j <= prime[0]; ++j)
		{

			if(ta % prime[j] == 0)
			{
				temp[++temp[0]] = prime[j];
				if(!used[prime[j]])
				{
					bktprimes[++bktprimes[0]] = prime[j];
					used[prime[j]] = 1;
				}
			}
			while(ta % prime[j] == 0)
			{
				ta /= prime[j];
			}
		}
		if(ta != 1)
		{
			temp[++temp[0]] = ta;
			if(!used[ta])
			{
				bktprimes[++bktprimes[0]] = ta;
				used[ta] = 1;
			}
		}
		finddiv(1);
	}
	d[1] = 0;
	sort(bktprimes + 1, bktprimes + bktprimes[0] + 1);
	sol = (long long) n * (n - 1);
	sol /= 2;
	bkt(1);

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

	return 0;
}

void ciur()
{
	int i, j;

	for(i = 2; i < 1024; ++i)
	{
		if(!v[i])
		{
			prime[++prime[0]] = i;
			for(j = 2 * i; j < 1024; j += i)
			{
				v[j] = 1;
			}
		}
	}
}

void finddiv(int k)
{
	if(k == temp[0] + 1)
	{
		++d[nr];
	}
	else
	{
		finddiv(k + 1);
		nr *= temp[k];
		finddiv(k + 1);
		nr /= temp[k];
	}
}

void bkt(int k)
{
	if(k == bktprimes[0] + 1)
	{
		long long temp;
		temp = (long long)d[nr] * (d[nr] - 1);
		temp /= 2;
		if(cnt % 2 == 1)
		{
			sol -= temp;
		}
		else
		{
			sol += temp;
		}
	}
	else
	{
		if(1000000 / bktprimes[k] >= nr)
		{
			nr *= bktprimes[k];
			++cnt;
			bkt(k + 1);
			--cnt;
			nr /= bktprimes[k];
		}
		if(1000000 / bktprimes[k] >= nr)
		{
			bkt(k + 1);
		}
		else
		{
			bkt(bktprimes[0] + 1);
		}
	}
}