Cod sursa(job #2497916)

Utilizator SergiuS3003Sergiu Stancu Nicolae SergiuS3003 Data 23 noiembrie 2019 12:18:16
Problema Pairs Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <iostream>
#include <fstream>
#include <bitset>

using namespace std;

const int VMAX = 1000001;

int N, xMax;

bitset<VMAX> M;
///Vector caracteristic al multimii de numere distincte M
///M[i] = 1 <==> i apartine multimii M

unsigned char nrdiv[VMAX];
///nrdiv[i] = cate numere prime distincte apar in descompunerea
///           in factori a lui i

bitset<VMAX> ciurp;
///Vector caracteristic al numerelor pentru care descompunerea
///in factori nu are factori primi distincti, adica:
///
///ciurp[i] = 1 <==> i are un divizor prim la o putere >= 2
///                 (i se divide cu patratul unui numar prim)

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

void citire()
{
    int x;
    f >> N;

    for ( int i = 1; i <= N; i++ )
    {
        f >> x;
        M[x] = 1;

        if ( x > xMax )
            xMax = x;
    }
}

int main()
{
    citire();
    long long sol = 1LL * N * ( N - 1 ) / 2;

    for ( int i = 2; i <=  xMax; i++ )
    {
        if ( nrdiv[i] == 0 )
        {
            ///Crestem numarul factorilor primi pentru numerele
            ///divizibile cu i
            for ( int j = i; j <= xMax; j += i )
                nrdiv[j]++;
        }

        //
        if ( ciurp[i] == 0 )
        {
            ///Marcam toti multiplii de i * i
            long long ii = 1LL * i * i;

            for ( long long jj = ii; jj <= xMax; jj += ii )
                ciurp[jj] = 1;

            //
            ///Determinam cate dintre numerele i, 2*i, 3*i,...,[xMax/i]*i
            ///apartin multimii M
            long long rez = 0;

            for ( int j = i; j <= xMax; j += i )
                if ( M[j] == 1 )
                    rez++;

            //
            rez = rez * ( rez - 1 ) / 2;

            if ( nrdiv[i] % 2 == 0 )
                sol += rez;
            else
                sol -= rez;
        }
    }

    g << sol;
    f.close();
    g.close();
    return 0;
}