Cod sursa(job #1713627)

Utilizator killer301Ioan Andrei Nicolae killer301 Data 6 iunie 2016 01:18:54
Problema Indep Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 6.43 kb
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int NMAX = 500;
const int CIFMAX = 500;

int n, Max;
int a[NMAX+5];

void add( int A[], int B[] ) {
    int i, t = 0;
    for( i = 1; i <= A[0] || i <= B[0] || t; i ++, t /= 10 )
        A[i] = ( t += A[i] + B[i] ) % 10;
    A[0] = i - 1;
    return;
}

void sub( int A[], int B[] ) {
    int i, t = 0;
    for( i = 1; i <= A[0]; i ++ ) {
        A[i] -= ( (i <= B[0]) ? B[i] : 0 ) + t;
        A[i] += ( t = A[i] < 0 ) * 10;
    }
    while( A[0] > 1 && !A[ A[0] ] )
        A[0] --;
    return;
}

vector <int> primes;
int p2[NMAX+5][CIFMAX];
int Ans[NMAX+5];
bool ciur[1005];

void sieve(const int N = 1000)
{
    ciur[0] = ciur[1] = true;
    for(int i=4; i<=N; i+=2)
        ciur[i] = true;
    int lim = (int)sqrt(1.0*N);
    for(int i=3; i<=lim; i+=2)
        if(ciur[i]==0)
            for(int j=i*i; j<=N; j+=2*i)
                ciur[j] = true;
    for(int i=2; i<=N; i++)
        if(ciur[i] == 0)
            primes.push_back(i);
}

void bkt(int pos, int prod, int e)
{
    if(e!=0)
    {
        int nr = 0;
        for(int i=0; i<n; i++)
            if(a[i]%prod == 0)
                nr++;
        if(e%2 == 0)
        {
//            Ans[0] = max(Ans[0], p2[nr][0]);
//            int c = 0;
//            for(int i=1; i<=Ans[0]; i++)
//            {
//                Ans[i] = Ans[i]+p2[nr][i]+c;
//                c=Ans[i]/10;
//                Ans[i]%=10;
//            }
//            if(c)Ans[++Ans[0]] = 1;
            add(Ans, p2[nr]);
        }
        else
        {
//            int c = 0;
//            for(int i=1; i<=Ans[0]; i++)
//            {
//                Ans[i] = Ans[i]-p2[nr][i]-c;
//                if(Ans[i]<0)
//                {
//                    Ans[i]+=10;
//                    c = 1;
//                }
//            }
//            while(Ans[0] > 1 && Ans[Ans[0]] == 0)Ans[0]--;
            sub(Ans, p2[nr]);
        }
    }
    for(int i=pos+1; i<primes.size(); i++)
        if(prod*primes[i]<=Max)
            bkt(i, prod*primes[i], e+1);
}

int main()
{
    freopen("indep.in", "r", stdin);
    freopen("indep.out", "w", stdout);
    sieve();
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
        Max = max(Max, a[i]);
    }
    p2[0][0] = 1;
    for(int i=1; i<=n; i++)
    {
        p2[i][0] = p2[i-1][0];
        int c = 0;
        for(int j=1; j<=p2[i][0]; j++)
        {
            p2[i][j] = p2[i-1][j]*2+c;
            c = p2[i][j]/10;
            p2[i][j]%=10;
        }
        if(c)p2[i][++p2[i][0]] = 1;
        p2[i][1]++;
    }
    for(int i=0; i<=p2[n][0]; i++)
        Ans[i] = p2[n][i];
    bkt(-1, 1, 0);
    for(int i=Ans[0]; i>0; i--)
        printf("%d", Ans[i]);
    printf("\n");
    return 0;
}



//#include <cstdio>
//#include <cmath>
//#include <cstring>
//#include <algorithm>
//
//using namespace std;
//
//const int NMAX = 500;
//const int CIFMAX = 300;
//
//int a[NMAX+5];
//int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 27, 29, 31, 37, 41};
//
//class HN
//{
//private:
//    int n;
//    int a[CIFMAX];
//public:
//    HN()
//    {
//        n = 1;
//        memset(a, 0, sizeof(a));
//    }
//    HN(int x)
//    {
//        n = 0;
//        memset(a, 0, sizeof(a));
//        do
//        {
//            a[n++] = x%10;
//            x/=10;
//        }
//        while(x);
//    }
//    HN &operator + (const HN &other)
//    {
//        HN ans;
//        ans.n = max(n, other.n);
//        int c = 0;
//        for(int i=0; i<ans.n; i++)
//        {
//            ans.a[i] = a[i]+other.a[i]+c;
//            c = ans.a[i]/10;
//            ans.a[i]%=10;
//        }
//        if(c) ans.a[ans.n++] = c;
//        return ans;
//    }
//    HN &operator - (const HN &other)
//    {
//        HN ans;
//        ans.n = n;
//        int c = 0;
//        for(int i=0; i<n; i++)
//        {
//            ans.a[i] = a[i]-other.a[i]-c;
//            if(ans.a[i] < 0)
//            {
//                c=1;ans.a[i]+=10;
//            }
//        }
//        while(ans.n>1 && ans.a[ans.n-1] == 0)ans.n--;
//        return ans;
//    }
//    HN operator * (const HN &other)
//    {
//        HN ans;
//        int m = other.n;
//        for(int i=0; i<n; i++)
//        {
//            for(int j=0; j<m; j++)
//            {
//                ans.a[i+j] += a[i]*other.a[j];
//            }
//        }
//        int c = 0;
//        for(int i=0; i<n+m-1; i++)
//        {
//            ans.a[i]+=c;
//            c = ans.a[i]/10;
//            ans.a[i]%=10;
//        }
//        ans.n = n+m-1;
//        if(c)
//        {
//            ans.a[ans.n++] = c%10;
//            c/=10;
//        }
//        if(c)ans.a[ans.n++] = c;
//        return ans;
//    }
//    void print()
//    {
//        for(int i=n-1; i>=0; i--)
//            printf("%d", a[i]);
//        printf("\n");
//    }
//};
//
//HN p2[NMAX+5];
//
//int main()
//{
//    freopen("indep.in", "r", stdin);
//    freopen("indep.out", "w", stdout);
//    int n;
//    scanf("%d", &n);
//    int Max = -1;
//    for(int i=0; i<n; i++)
//    {
//        scanf("%d", &a[i]);
//        Max = max(Max, a[i]);
//    }
//    HN p = 1;
//    for(int i=0; i<=n; i++)
//    {
//        p2[i] = p;
//        p = p*(HN)2;
//    }
//    HN Ans;
//    for(int i=2; i<=Max; i++)
//    {
//        int lim = (int)sqrt(1.0*i);
//        int pos = 0, e = 0;
//        int c = i;
//        bool ok = true;
//        while(primes[pos]<=lim)
//        {
//            if(c%primes[pos] == 0)
//            {
//                c/=primes[pos];
//                e++;
//            }
//            if(c%primes[pos] == 0)
//            {
//                ok = false;
//                break;
//            }
//            pos++;
//        }
//        if(!ok)continue;
//        int nr = 0;
//        for(int j=0; j<n; j++)
//            if(a[j]%i == 0)
//                nr++;
//        if(c>1)e++;
//        if(e%2==1)
//        {
//            Ans = Ans + p2[nr];
//            Ans = Ans - (HN)1;
//        }
//        else
//        {
//            Ans = Ans - p2[nr];
//            Ans = Ans + (HN)1;
//        }
//    }
//    Ans = p2[n] - Ans;
//    Ans = Ans - 1;
//    Ans.print();
//    return 0;
//}