Cod sursa(job #2735075)

Utilizator marius004scarlat marius marius004 Data 1 aprilie 2021 19:51:48
Problema Indep Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.51 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>

using namespace std;

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

const int NMAX = 1001;
const int BIG_INT_LEN = 10001;

int n, arr[NMAX], sol[BIG_INT_LEN];
bitset < NMAX > isPrime, isFactor;
vector < int > primes, factors;

void copy(int *a, int* b) {
    for(int i = 0;i <= b[0];++i)
        a[i] = b[i];
}

void multiply(int *a, int* b) {

    int c[BIG_INT_LEN]; /// c = a * b
    memset(c, 0, sizeof c);

    c[0] = a[0] + b[0] - 1;

    for(int i = 1;i <= a[0];++i)
        for(int j = 1;j <= b[0];++j)
            c[i + j - 1] += a[i] * b[j];

    int t{};
    for(int i = 1;i <= c[0];++i) {
        t = (c[i] += t) / 10;
        c[i] %= 10;
    }

    if(t)
        c[++c[0]] = t;

    copy(a, c);
}


void add(int* a, int* b) {

    if (b[0] > a[0]) {
        for (int i = a[0] + 1; i <= b[0];)
            a[i++]=0;

        a[0] = b[0];
    } else {
        for(int i = b[0] + 1;i <= a[0];)
            b[i++] = 0;
    }

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

    if(t)
        a[++a[0]] = t;
}

void subtract(int* a, int* b) {

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

    int t{};
    for (int i = 1;i <= a[0];i++)
        a[i] += (t = (a[i] -= b[i] + t) < 0 ) ? 10 : 0;

    for(;!a[ a[0]] && a[0] > 1;)
        a[0]--;
}

/// Calculate 2^n on BigInt
void buildPowerOf2(int *a, int b) {

    a[0] = 1;

    if(b == 0) {
        a[1] = 1;
        return;
    }

    a[1] = 2;

    int sol[BIG_INT_LEN];
    memset(sol, 0, sizeof sol);

    sol[0] = sol[1] = 1;

    for(;b; b /= 2) {

        if(b & 1)
            multiply(sol, a);

        multiply(a, a);
    }

    copy(a, sol);
}

void doSieve() {

    isPrime[0] = isPrime[1] = 1;

    for(int i = 2;i + i <= NMAX;i += (i == 2 ? 1 : 2)) {
        if (!isPrime[i]) {

            primes.push_back(i);

            for(int j = i + i;j <= NMAX;j += i)
                isPrime[j] = 1;
        }
    }
}

int main() {

    f >> n;

    doSieve();
    buildPowerOf2(sol, n);

    for(int index = 1;index <= n;++index) {
        f >> arr[index];

        /// violez SOLID ;(((((

        int nr = arr[index];
        for(int i = 0;i < primes.size() && primes[i] * primes[i] <= nr;++i) {
            if(nr % primes[i] == 0) {

                if(!isFactor[primes[i]]) {
                   isFactor[primes[i]] = 1;
                   factors.push_back(primes[i]);
               }

               for(;nr % primes[i] == 0; nr /= primes[i]);
            }
        }

        if(nr > 1 && !isFactor[nr]) {
            isFactor[nr] = 1;
            factors.push_back(nr);
        }
    }

    int lim = (1 << factors.size()) - 1;

    for(int mask = 1;mask <= lim;++mask) {

        int counter{};
        int prod{1};

        for(int i = 0;i < factors.size();++i) {
            if(((mask >> i) & 1) == 1) {
                counter++;
                prod *= factors[i];
            }
        }

        if(counter > 0) {

            int pow2{};
            for(int i = 1;i <= n;++i)
                if(arr[i] % prod == 0)
                    pow2++;

            if(pow2 != 0) {

                int aux[BIG_INT_LEN];
                memset(aux, 0, sizeof aux);

                buildPowerOf2(aux, pow2);

                if(counter % 2 == 1)
                    subtract(sol, aux);
                else
                    add(sol, aux);
            }
        }
    }

    for(int i = sol[0];i > 0;--i)
        g << sol[i];

    return 0;
}