Cod sursa(job #1851171)

Utilizator Coroian_DavidCoroian David Coroian_David Data 19 ianuarie 2017 14:19:55
Problema Indep Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.69 kb
#include <cstdio>

using namespace std;

FILE *f, *g;

int n;

int v[1001], kCiur;

bool p[1001];

int ap[1001];
int apPr[1001];

int rez[100001];
int p2[1001][1001];

int stk[20];

bool apProd[1001];

int scad[100001];

inline int mxa(int a, int b)
{
    return (a > b ? a : b);
}

void ciur()
{
    int i, j;
    int n = 1000;

    p[0] = p[1] = 1;

    for(i = 4; i <= n; i += 2)
        p[i] = 1;

    for(i = 3; i * i <= n; i += 2)
    {
        if(p[i] == 0)
        {
            for(j = i * i; j <= n; j += i * 2)
                p[j] = 1;
        }
    }

    v[++ kCiur] = 2;

    for(i = 3; i <= n; i += 2)
    {
        if(p[i] == 0)
            v[++ kCiur] = i;
    }
}
/*
void desc(int nr)
{
    int d = 1;
    int p = 0;

    while(nr % v[d] == 0)
        nr /= v[d], p ++;

    if(p > 0)
        ap[v[d]] += p;

    while(d <= kCiur && v[d] * v[d] <= nr)
    {
        p = 0;

        while(nr % v[d] == 0)
            nr /= v[d], p ++;

        if(p > 0)
            ap[v[d]] += p;

        d ++;
    }

    if(nr > 1)
        ap[nr] ++;
}*/

void readFile()
{
    f = fopen("indep.in", "r");

    fscanf(f, "%d", &n);

    int i, nr;
    for(i = 1; i <= n; i ++)
    {
        fscanf(f, "%d", &nr);

        //desc(nr);

        ap[nr] ++;
    }

    fclose(f);
}

void aduna(int a[], int b[])
{
    int i;
    int mx = mxa(a[0], b[0]), t = 0;

    for(i = 1; i <= mx || (t > 0); i ++)
    {
        t = a[i] + b[i] + t;

        a[i] = t % 10;

        t /= 10;
    }

    a[0] = i - 1;
}

void scade(int a[], int b[])
{
    int i;
    int t = 0;

   // printf("**%d %d\n", a[0], b[0]);

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

        if(a[i] < 0)
            t = 1, a[i] += 10;

        else
            t = 0;
    }

    if(t > 0)
        a[i] --;

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

void adunaScalar(int a[], int nr)
{
    int b[2] = {1, nr};

    aduna(a, b);
}

void scadeScalar(int a[], int nr)
{
    int b[2] = {1, nr};

    scade(a, b);
}

void copyV(int a[], int b[])
{
    int i;

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

void getP2()
{
    p2[1][0] = 1;
    p2[1][1] = 2;

    int i;
    for(i = 2; i <= 500; i ++)
    {
        copyV(p2[i], p2[i - 1]);

        aduna(p2[i], p2[i]);
    }
}

int prod = 1;

void scrie(int a[])
{
    int i;
    for(i = a[0]; i >= 1; i --)
        printf("%d", a[i]);

    printf("*\n");
}

void bkt(int k)
{
    if(prod <= 1000 && k <= 5)
    {
        stk[k] = stk[k - 1] + 1;

      //  printf("*%d %d\n", stk[k], k);
        int i;
        for(i = stk[k - 1] + 1; i <= kCiur && prod <= 1000; i ++)
        {
            if(ap[v[i]] > 0)
            {
                stk[k] = i;

                prod *= v[stk[k]];

              //  printf("%d %d %d\n", prod, stk[k], k);

                if(prod <= 1000 && apProd[prod] == 0)
                {
                    apProd[prod] = 1;//, printf("%d %d\n", prod, apPr[prod]);

                    int sign;

                    if(k % 2 == 1)
                        sign = -1;

                    else
                        sign = 1;

                    if(sign == 1)
                    {
                        aduna(rez, p2[apPr[prod]]);
                        scadeScalar(rez, 1);

                     //   scrie(rez);
                    }

                    else
                    {
                        aduna(scad, p2[apPr[prod]]);

                         //        scrie(scad);
                        scadeScalar(scad, 1);

                       // scrie(scad);
                    }

                    bkt(k + 1);
                }

                prod /= v[stk[k]];
            }
        }
    }
}

struct factor
{
    int nr, p;
};

factor fact[101];

void descAp(int nr, int i)
{
    int j;

    for(j = i; j <= 1000; j += i)
        apPr[i] += ap[j];
}

void getAp()
{
    int i;
    for(i = 1; i <= 1000; i ++)
        descAp(i, i);//, printf("%d %d\n", apPr[i], i);

    //printf("%d %d\n", ap[2], ap[3]);
}

void solve()
{

//    int i;
//    for(i = 1; i <= kCiur; i ++)
//        printf("%d ", v[i]);

    getP2();

    getAp();

    bkt(1);

    aduna(rez, p2[n]);
    scadeScalar(rez, 1);

    scade(rez, scad);
}

void printFile()
{
    g = fopen("indep.out", "w");

    int i;
    for(i = rez[0]; i >= 1; i --)
        fprintf(g, "%d", rez[i]);

    fclose(g);
}

int main()
{
    ciur();

    readFile();

    solve();

    printFile();

    return 0;
}