Cod sursa(job #2161446)

Utilizator Daria09Florea Daria Daria09 Data 11 martie 2018 18:42:09
Problema Indep Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <iostream>
#include <fstream>
#include <math.h>
#define CMAX 100005
#define NMAX 505
#define CIURMAX 1005
using namespace std;
ifstream f("indep.in");
ofstream g("indep.out");
int p2[NMAX][CMAX],ans[CMAX],prim[CIURMAX];
int n,a[NMAX],MAX,nr,semn;
bool ciur[CIURMAX];
void prelucrare()
{
    p2[0][0]=p2[0][1]=1;
    for(int i=1; i<=500; i++)
    {
        for(int j=0; j<=p2[i-1][0]; j++)
            p2[i][j]=p2[i-1][j];
        int t=0,p;
        for(int j=1; j<=p2[i][0]; j++)
        {
            p=p2[i][j]*2+t;
            t=p/10;
            p2[i][j]=p%10;
        }
        if(t!=0)
        {
            p2[i][0]++;
            p2[i][p2[i][0]]=t;
        }
    }
    prim[1]=2;
    nr=1;
    for(int i=4; i<=1000; i+=2)
        ciur[i]=1;
    for(int i=3; i<=1000; i+=2)
        if(ciur[i]==0)
        {
            prim[++nr]=i;
            for(int j=2*i; j<=1000; j+=i)
                ciur[j]=1;
        }
}
void read()
{
    f>>n;
    for(int i=1; i<=n; i++)
        f>>a[i],MAX=max(MAX,a[i]);
    f.close();
}
int verif(int x)
{
    int sol=0;
    for(int i=1; i<=nr&&prim[i]<=x; i++)
    {
        int ok=0;
        while(x%prim[i]==0)
        {
            ok++;
            x/=prim[i];
        }
        if(ok>1)
            return 0;
        else if(ok==1)
            sol++;
    }
    return sol;
}
int div(int x)
{
    int sol=0;
    for(int i=1; i<=n; i++)
        if(a[i]%x==0)
            sol++;
    return sol;
}
void adunare(int x)
{
    int t=0,s;
    for(int i=1; i<=max(ans[0],p2[x][0]); i++)
    {
        s=ans[i]+p2[x][i]+t;
        ans[i]=s%10;
        t=s/10;
    }
    ans[0]=max(ans[0],p2[x][0]);
    if(t!=0)
        ans[++ans[0]]=t;
}
void scadere(int x)
{
    int t=0,s;
    for(int i=1;i<=max(ans[0],p2[x][0]);i++)
    {
        s=ans[i]-p2[x][i]-t;
        ans[i]=(10+s)%10;
        t=1-(10+s)/10;
    }
    if(t!=0)
    {
        semn=-semn;
        ans[++ans[0]]=t;
    }
    while(ans[ans[0]]==0&&ans[0]>0)ans[0]--;
}
void write();
void solve()
{
    int x=n;
    semn=1;
    adunare(n);
    for(int i=2; i<=MAX; i++)
    {
        int ok=verif(i);
        if(ok==0)continue;
        int s=div(i);
        if(s!=0)
        {
            if((ok%2==0&&semn==1)||(semn==-1&&ok%2==1))
                adunare(s);
            else
                scadere(s);
        }
    }
}
void write()
{
    for(int i=ans[0]; i>=1; i--)
        g<<ans[i];
    g<<'\n';
}
int main()
{
    prelucrare();
    read();
    solve();
    write();
    return 0;
}