Cod sursa(job #3146708)

Utilizator lensuLensu Alexandru lensu Data 22 august 2023 11:53:22
Problema Indep Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.32 kb
#include <fstream>
#include <vector>
#define int long long

using namespace std;
//
ifstream cin("indep.in");
ofstream cout("indep.out");

const int NMAX = 1001;

typedef long long NrMare[NMAX+1];

int N, Fact[NMAX+1], ans[NMAX+1], finalans[NMAX+1];
vector<int> prime;
bool eprim[NMAX+1];

void Add(NrMare x,NrMare y)
// x = x + y
{
  int i,t=0;
  if(x[0]<y[0])
    x[0]=y[0];
  for(i=1;i<=x[0];i++,t/=10)
  {
    t=x[i]+y[i]+t;
    x[i]=t%10;
    // echivalent x[i]=(t+=x[i]+y[i])%10
  }
  if(t)
    x[++x[0]]=t;
}

void Scazi(NrMare x, NrMare y)
// x <-- x-y
{
  int i,j, t = 0;
  for (i = 1; i <= x[0]; i++)
    if(x[i]>=y[i])
      x[i]-=y[i];
    else
    {
      j=i+1;
      while(x[j]==0)
        x[j++]=9;
      x[j]--;
      x[i]=10+x[i]-y[i];
    }
  for (; x[0] > 1 && !x[x[0]]; x[0]--); // sa n-am zerouri nesemnificative
}

void Produs(NrMare x, int n)
//x <- x*n
{
  int i,t=0;
  for(i=1;i<=x[0];i++,t/=10)
  {
    t+=x[i]*n;
    x[i]=t%10;
  }
  for(;t;t/=10)
    x[++x[0]]=t%10;
}

void eratostene()
{
    for(int i = 3; i <= NMAX; i+= 2)
    {
        if(eprim[i] == 0)
            for(int j = i + i; j <= NMAX; j += i)
                eprim[j] = 1;
    }

    prime.push_back(2);
    for(int i = 3; i <= NMAX; i++)
    {
        if(eprim[i] == 0 && i % 2)
            prime.push_back(i);
    }
}

void rez(vector<int> &sub, int n, vector<int> &factori)
{
    int P = 1;
    for(int i = 1; i <= n; i++)
        P = P * factori[sub[i]];
    if(n % 2 == 1)
    {
        long long termen[NMAX+1];
        termen[0] = 1, termen[1] =1;
        for(int i = 1; i <= Fact[P]; i++)
        {
            Produs(termen,2);
        }
        Add(ans,termen);
    }
    else
    {
        long long termen[NMAX+1];
        termen[0] = 1, termen[1] =1;
        for(int i = 1; i <= Fact[P]; i++)
        {
            Produs(termen,2);
        }
        Scazi(ans, termen);
    }
    Fact[P]++;
}

void Back(vector<int> &sub, int k, vector<int> &elem)
{
    for(int i =  sub[k-1] + 1; i < elem.size(); i++)
    {
        sub[k] = i;
        rez(sub,k,elem);
        if(k < elem.size())
        {
            Back(sub, k + 1, elem);
        }
    }
}
void Desc(int B)
{
    vector<int> factoriprimi;
    int ind = 0, d = prime[0];
    while(B != 1)
    {
        if(B % d == 0)
        {
            factoriprimi.push_back(d);
            while(B % d == 0)
                B /= d;
        }
        if(prime[ind+1] * prime[ind+1] > B)
            d = B;
        else d = prime[++ind];
    }

    vector<int> submultimi(factoriprimi.size()+1);
    submultimi[0] = -1;
    Back(submultimi, 1, factoriprimi);
}

signed main()
{
    eratostene();
    cin >> N;
    ans[0] = 1;
    finalans[0] = 1, finalans[1] = 0;
    for(int i = 1; i <= N; i++)
    {
        int x, B;
        cin >> x;
        B = x;
        Desc(B);

        int aux[NMAX+1];
        aux[0] = 1, aux[1] = 1;
        for(int j = 1; j <= i-1; j++)
        {
            Produs(aux,2);
        }
        Scazi(aux,ans);
        Add(finalans,aux);
        if(i != N)
        {
            for(int j = 1; j <= ans[0]; j++)
                ans[j] = 0;
            ans[0] = 1;
        }
    }
    for(int i = 1; i <= finalans[0]; i++)
        cout << finalans[i];
}