Cod sursa(job #1964569)

Utilizator BugirosRobert Bugiros Data 13 aprilie 2017 15:13:10
Problema Pairs Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.67 kb
#include <fstream>
using namespace std;

const int MAXNR = 1000005;

ifstream in("pairs.in");
ofstream out("pairs.out");

bool exista[MAXNR];

int n;

int maxnr;

void citire()
{
    in >> n;
    for (int i = 1;i <= n;++i)
    {
        int x;
        in >> x;
        exista[x] = true;
        if (x > maxnr)
            maxnr = x;
    }
}


//catenumereprime[i] - cate numere prime distincte apar in descompunerea lui i
int catenumereprime[MAXNR];


//calculam cate perechi de numere sunt neprime intre ele
//folosind principiul includerii si al excluderii
long long neprime;

void ciur()
{
    for (int i = 2;i <= maxnr;++i)
        if (catenumereprime[i] == 0)
            for (int j = i;j <= maxnr;j += i)
                ++catenumereprime[j];

    //vom elimina numerele care au  un divizor prim la cel putin puterea a 2-a
    //deoarece ne trebuie doar acele numere care sunt produs de numere prime distincte
    for (int i = 2;i * i <= maxnr;++i)
        for (int j = i * i;j <= maxnr;j += i * i)
        //eliminam toti multiplii de i * i, care au cel putin puterea a 2-a
            catenumereprime[j] = -1;
}

void prelucrare()
{
    for (int i = 2;i <= maxnr;++i)
    {
        if (catenumereprime[i] == -1)
            continue;
        int nr = 0;
        for (int j = i;j <= maxnr;j += i)
            if (exista[j])
                ++nr;
        if (catenumereprime[i] % 2 == 1)
            neprime += (long long)nr * (nr - 1) / 2;
        else neprime -= (long long)nr * (nr - 1) / 2;
    }
}

int main()
{
    citire();
    ciur();
    prelucrare();
    out << (long long)n * (n - 1) / 2 - neprime;
    return 0;
}