Cod sursa(job #2985105)

Utilizator Zed1YasuoAlex Birsan Zed1Yasuo Data 25 februarie 2023 17:57:40
Problema Indep Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.44 kb
#include <fstream>
#include <vector>
#include <cmath>
///fara numere mari
#define ll long long
using namespace std;
ifstream f("indep.in");
ofstream g("indep.out");
int n,a[1005],x,ciur[1005];
int d[1005][1005];
int ex[1005][1000];
int ans[1005];
vector<int>fct;
void adunare(int A[],int B[])
{
    int last=0;
    int nr=max(A[0],B[0]);
    for(int i=1; i<=nr; i++)
    {
        A[i]=(A[i]+B[i]+last);
        last=A[i]/10;
        A[i]%=10;
    }
    while(last)
    {
        A[++nr]=last%10;
        last/=10;
    }
    A[0]=nr;
}
void scadere(int A[],int B[])
{
    int last=0;
    for(int i=1;i<=A[0];i++)
    {
        if(A[i]>=B[i])
            A[i]-=B[i];
        else
        {
            int j=i+1;
            while(!A[j])
                A[j++]=9;
            A[j]--;
            A[i]=10+A[i]-B[i];
        }
    }
    while(A[0]>1&&!A[A[0]])
        A[0]--;
}
void inmultire(int p1,int p2)
{
    int last=0;
    ex[p1][0]=ex[p2][0];
    for(int i=1; i<=ex[p2][0]; i++)
    {
        ex[p1][i]=(ex[p2][i]*2+last);
        last=ex[p1][i]/10;
        ex[p1][i]%=10;
    }
    while(last)
    {
        ex[p1][++ex[p1][0]]=last%10;
        last/=10;
    }
}
void precalc()
{
    ex[0][0]=1;
    ex[0][1]=1;
    for(int i=1; i<=1000; i++)
    {
        inmultire(i,i-1);
    }
}
int main()
{
    f>>n;
    precalc();
    for(int i=2; i*i<=1000; i++)
        if(ciur[i]==0)
            for(int j=i*i; j<=1000; j+=i)
                ciur[j]=true;
    for(int i=1; i<=n; i++)
    {
        f>>x;
        for(int j=1; j*j<=x; j++)
            if(x%j==0)
                a[j]++,a[x/j]++;
        if(sqrt(x)==int(sqrt(x)))
            a[int(sqrt(x))]--;
    }
    for(int i=1; i<=1000; i++)
    {
        if(a[i])
            adunare(d[i],ex[a[i]]);
        //         d[i]=(1<<a[i])-1;
    }
    for(int i=2; i<=1000; i++)
        if(a[i]&&ciur[i]==0)
            fct.push_back(i);
    int all=(1<<fct.size());
    adunare(ans,d[1]);
    for(int i=1; i<all; i++)
    {
        int bits=0;
        ll r=1;
        for(int j=0; j<fct.size(); j++)
            if(i&(1<<j))
            {
                bits++;
                r*=fct[j];
            }
        if(r>1000)
            break;
        if(bits%2)
            scadere(ans,d[r]);
        else
            adunare(ans,d[r]);
    }
    for(int i=ans[0];i>0;i--)
        g<<ans[i];
    // g<<ans;
    return 0;
}