Cod sursa(job #1404401)

Utilizator mircea.dobreanuMircea Dobreanu mircea.dobreanu Data 28 martie 2015 08:47:48
Problema Pairs Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.78 kb
#include <bitset>
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;

ifstream fin("pairs.in");
ofstream fout("pairs.out");
const int kMax = 1e5 + 5;
const int kSqrt = 1e3 + 1;
const int kVal = 1e6 + 1;
int n, v[kMax];
bitset<kVal> isPrime;
vector<int> primeList, divisors;

void sieve()
{
	isPrime.set();
	isPrime[0] = isPrime[1] = false;

	primeList.push_back(2);
	for (int j = 4; j < kVal; j += 2)
		isPrime[j] = false;

	for (int i = 3; i < kVal; i += 2)
	{
		if (isPrime[i])
		{
			primeList.push_back(i);
			if (i < kSqrt)
				for (int j = i * i; j < kVal; j += i)
					isPrime[j] = false;
		}
	}

}

int cardDivBy(int divisor)
{
	int res = 0;
	for (int i = 1; i <= n; ++i)
		if (v[i] % divisor == 0)
			++res;
	return res;
}

long long noPairs(int card)
{
	return 1LL * card * (card - 1) / 2;
}

int main()
{
    sieve();
	fin >> n;
	for (int i = 1; i <= n; ++i)
		fin >> v[i];

	for (int i = 1; i <= n; ++i)
	{
		int cpy = v[i];

		for (size_t j = 0; j < primeList.size(); ++j)
		{
			if (!(cpy % primeList[j]))
			{
				divisors.push_back(primeList[j]);
                while (!(cpy % primeList[j]))
					cpy /= primeList[j];
			}
		}
	}

	sort(divisors.begin(), divisors.end());
	divisors.erase(unique(divisors.begin(), divisors.end()), divisors.end());

	int bits = divisors.size(), sz = (1 << divisors.size());
	long long res = 0;

	for (int bitMask = 0; bitMask < sz; ++bitMask)
	{
		int noBits = 0, factor = 1;
		for (int i = 0; i < bits; ++i)
		{
			if (bitMask & (1 << i))
			{
				++noBits;
				factor *= divisors[i];
			}
		}
		if (noBits % 2)
            res -= noPairs(cardDivBy(factor));
		else
			res += noPairs(cardDivBy(factor));
	}

	fout << res << '\n';
	return 0;
}