Cod sursa(job #1772347)

Utilizator borcanirobertBorcani Robert borcanirobert Data 6 octombrie 2016 17:57:10
Problema Indep Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <fstream>
using namespace std;

ifstream fin("indep.in");
ofstream fout("indep.out");

const int MAXN = 505;
const int MAXNR = 10005;
using NrMare = int[MAXNR];
int N;
int maxim;
int a[MAXN];
int D[MAXNR];
NrMare Z[MAXNR];
NrMare rez;
NrMare p2[MAXNR];
NrMare s;
NrMare unu;

void Read();
void Solve();
void Write();
void Add( NrMare a, NrMare b );
void Scade( NrMare a, NrMare b );
void Copiere( NrMare d, NrMare s );

int main()
{
    Read();
    Solve();
    Write();

    fin.close();
    fout.close();
    return 0;
}

void Read()
{
    int i;

    fin >> N;
    for ( i = 1; i <= N; i++ )
    {
        fin >> a[i];
        maxim = max( maxim, a[i] );
    }
}

void Solve()
{
    int i, j;
    unu[0] = unu[1] = 1;

    for ( i = 1; i <= N; i++ )
    {
        for ( j = 1; j <= a[i]; j++ )
            if ( a[i] % j == 0 )
                D[j]++;
    }

    p2[0][0] = p2[0][1] = 0;
    s[0] = s[1] = 1;

    for ( i = 1; i <= maxim; i++ )
    {
        Copiere(p2[i], s);
        Add(p2[i], s);
        Copiere(s, p2[i]);
        Scade(p2[i], unu);
    }

    for ( i = 1; i <= maxim; i++ )
    {
        Copiere(Z[i], p2[D[i]]);
    }

    Copiere(rez, Z[1]);

    for ( i = 2; i <= maxim; i++ )
    {
        int x = i, np = 0;

        for ( j = 2; x > 1; j++ )
            if ( x % j == 0 )
            {
                x /= j;
                np++;
                if ( x % j == 0 )
                    break;
            }

        if ( x > 1 ) continue;

        if ( np % 2 == 0 )
            Add(rez, Z[i]);
        else
            Scade(rez, Z[i]);
    }
}

void Write()
{
    int i;

    if ( rez[0] == 0 )
    {
        fout << "0" << '\n';
        return;
    }

    for ( i = rez[0]; i >= 1; i-- )
        fout << rez[i];
    fout << '\n';
}

void Add( NrMare a, NrMare b )
{
    int i, cif, t = 0;

    for ( i = 1; i <= max(a[0], b[0]); i++ )
    {
        cif = t + a[i] + b[i];
        a[i] = cif % 10;
        t = cif / 10;
    }

    a[0] = max( a[0], b[0] );
    while ( t > 0 )
        a[++a[0]] = t % 10, t /= 10;
}

void Scade( NrMare a, NrMare b )
{
    int i;

    for ( i = b[0] + 1; i <= a[0]; i++ )
        b[i] = 0;

    int t = 0, cif;

    for ( i = 1; i <= a[0]; i++ )
    {
        cif = t + a[i] - b[i]; t = 0;
        while ( cif < 0 )
            cif = cif + 10, t--;
        a[i] = cif;
    }

    while ( a[a[0]] == 0 && a[0] > 0 ) --a[0];
}

void Copiere( NrMare d, NrMare s )
{
    int i;

    for ( i = 0; i <= s[0]; i++ )
        d[i] = s[i];
}