Pagini recente » Cod sursa (job #2313956) | Cod sursa (job #292863) | Cod sursa (job #2849758) | Cod sursa (job #2504190) | Cod sursa (job #2951265)
#include <fstream>
#include <climits>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <bitset>
#include <map>
#include <cstring>
#include <algorithm>
#define NMAX 1000003
using namespace std;
ifstream fin("pairs.in");
ofstream fout("pairs.out");
int n, m;
int maxim = INT_MIN;
int nrDivPrimi[NMAX];//numarul de divizori primi ai numarului o
bool ePatratPerject[NMAX],frecv[NMAX];//daca e patrat perfect numarul i si daca exista in vectorul initial de numere
void facProcesari()
{
//aici fac ciurul si incerc sa imi procesez elementele
nrDivPrimi[1] = 1;//1 nu e prim duh
for (int i = 2; i <= maxim; i++)
{
if (nrDivPrimi[i] == 0)
{
//tac pac e prim
//parcurg toti multiplii lui i
for (int j = i; j <= maxim; j += i) {
nrDivPrimi[j]++;
if (j % (i * i) == 0)
{
//practic e multiplu de patrat perfect->e si el patrat perfect
ePatratPerject[j] = 1;
}
}
}
}
}
int main()
{
fin >> n;
for (int i = 1; i <= n; i++)
{
int x;
fin >> x;
maxim = max(maxim, x);//iau numarul maxim
frecv[x] = true;//pun ca am numarul asta
}
facProcesari();
long long int num = 0;//acuma vine pinex
for (int i = 2; i <= maxim; i++)
{
if (!ePatratPerject[i])
{
//nu e multiplu de patrat perfect
int cnt = 0;//merg cum am mers si la ciur si vad care sunt multiplii lui care apar printre numere
for (int k = i; k <= maxim; k+=i)
{
if (frecv[k] == true)
{
cnt++;
}
}
//acuma vine smecheria, daca am un numar par de divizori primi, inseamna ca am reuniunea a n intervale unde n par->se scad
if (nrDivPrimi[i] % 2 == 0)
{
num -= cnt * (cnt - 1) / 2;
}
else {
num += cnt * (cnt - 1) / 2;
}
}
}
fout << 1LL * n * (n - 1) / 2 - num;
return 0;
}