Cod sursa(job #1949124)

Utilizator BugirosRobert Bugiros Data 1 aprilie 2017 18:55:18
Problema Indep Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.74 kb
#include <fstream>
#include <vector>
using namespace std;

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

const int MAXN = 502;
const int MAXNR = 1001;

struct numar_mare
{
    vector<int> cifre;
    numar_mare()
    {
        cifre.push_back(0);
    }

    void aduna(numar_mare *b, numar_mare *c)
    {
        (c -> cifre).resize(max(cifre.size(),(b -> cifre).size()));
        int t = 0;
        for (unsigned int i = 0;i < (c -> cifre).size();++i, t /= 10)
        {
            if (i < cifre.size())
                t += cifre[i];
            if (i < (b -> cifre).size())
                t += (b -> cifre)[i];
            (c -> cifre)[i] = t % 10;
        }
        if (t != 0)
            (c -> cifre).push_back(t);
    }

    void scade(numar_mare *b, numar_mare *c)
    {
        (c -> cifre).resize(cifre.size());
        int t = 0;
        for (unsigned int i = 0;i < cifre.size();++i)
        {
            (c -> cifre)[i] = cifre[i];
            if (i < (b -> cifre).size())
                (c -> cifre)[i] -= (b -> cifre)[i];
            (c -> cifre)[i] -= t;
            if ((c -> cifre)[i] < 0)
            {
                (c -> cifre)[i] += 10;
                t = 1;
            }
            else t = 0;
        }
        while ((c -> cifre).size() > 1 && (c -> cifre)[(c -> cifre).size() - 1] == 0)
            (c -> cifre).pop_back();
    }

    void mul(int b, numar_mare *c)
    {
        int t = 0;
        c -> cifre.resize(cifre.size());
        for (unsigned int i = 0;i < cifre.size();++i, t /= 10)
        {
            t += cifre[i] * b;
            (c -> cifre)[i] = t % 10;
        }
        if (t != 0)
            (c -> cifre).push_back(t);
    }

    void afisare()
    {
        for (int i = cifre.size() - 1;i >= 0;--i)
            out << (int)cifre[i];
    }
};

int v[MAXN];
int n;
int k;

numar_mare put2[MAXN];

numar_mare unu;


int d(int x)
{
    int rasp = 0;
    for (int i = 1;i <= n;++i)
        if (v[i] % x == 0)
            ++rasp;
    return rasp;
}

numar_mare z(int x)
{
    int card = d(x);
    numar_mare rasp;
    put2[card].scade(&unu, &rasp);
    return rasp;
}

void generare_put2()
{
    put2[0].cifre[0] = 1;
    for (int i = 1;i <= n;++i)
        put2[i - 1].mul(2, &put2[i]);
}

void citire()
{
    in >> n;
    for (int i = 1;i <= n;++i)
    {
        in >> v[i];
        if (v[i] > k)
            k = v[i];
    }
}

numar_mare rezultat;
numar_mare rezultataux;
bool rezultat1 = true;

void prelucrare()
{
    rezultat = z(1);
    for (int i = 2;i <= k;++i)
    {
        int aux = i;
        bool steag = true;
        bool par = true;
        for (int d = 2;aux != 1;++d)
            if (aux % d == 0)
            {
                aux /= d;
                par = !par;
                if (aux % d == 0)//se imparte de doua ori, deci numarul i nu este produs de numere prime distincte
                {
                    steag = false;
                    break;
                }
            }
        if (steag)
        {
            numar_mare Z = z(i);
            if (par)
            {
                if (rezultat1)
                    rezultat.aduna(&Z, &rezultataux);
                else rezultataux.aduna(&Z, &rezultat);
            }
            else
            {
                if (rezultat1)
                    rezultat.scade(&Z,&rezultataux);
                else rezultataux.scade(&Z,&rezultat);
            }
            rezultat1 = !rezultat1;
        }
    }
}

int main()
{
    unu.cifre[0] = 1;
    citire();
    generare_put2();
    prelucrare();
    if (rezultat1)
        rezultat.afisare();
    else rezultataux.afisare();
    out << '\n';
    return 0;
}