Cod sursa(job #2032550)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 5 octombrie 2017 12:02:35
Problema Pairs Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <bits/stdc++.h>
#define nmax 1000005
using namespace std;
fstream f1("pairs.in", ios::in);
fstream f2("pairs.out", ios::out);
long int n, f[nmax], x[nmax], maxi, ciur[nmax], prime[nmax], nrprime, viz[nmax], a[nmax], nrell, l[nmax];
///rasp= nr de perechi de nr. cu cmmmdc> 1
///x[i]= nr de numere din M div cu i
void eratostene()
{
    long int i;
    long long int j;
    ciur[0]=ciur[1]=1;
    for(i=2; i<=maxi; i++)
        if(!ciur[i])
       {
           nrprime++;
           prime[nrprime]=i;
           for(j=i*2; j<=maxi; j+=i)
            ciur[j]=1;
       }
}
void descomp(long int val)
{
    long int i=1, lim=sqrt(val), ok;
    while((i<=nrprime)&&(val!=1))
    {
        if(prime[i]> lim) break;
        ok=0;
        while(val%prime[i]==0)
        {
            val/=prime[i];
            ok=1;
        }
        if(ok) viz[prime[i]]=1;
        i++;
    }
    if(val!=1) viz[val]=1;
}
int main()
{
    long long int i, j, bit, p,nr;
    long long int rasp=0, nrs;
    f1>>n;
    for(i=1; i<=n; i++) {f1>>a[i]; f[a[i]]=1; if(maxi< a[i]) maxi=a[i];}
    eratostene();
    for(i=2; i<=maxi; i++)
        for(j=i; j<=maxi; j+=i) ///verifici cati multipli ai lui i se afla in M
            if(f[j]) x[i]++;

    ///ex: daca avem nr div cu 2, 3, 5 nr de perechi de nr cu cmmdc> 1=
    ///nr de perechi de nr cu cmmmdc=2+ nr de perechi de nr cu cmmmdc=3+ nr de perechi de nr cu cmmmdc=5 (adica x2+x3+x5)
    ///- nr perechi de nr cu cmmdc=2*3- nr de perechi de nr cu cmmdc=3*5- nr de perechi de nr cu cmmdc=2*5 (adica -x(2*3)-x(2*5)-x(5*3))
    ///+ nr perechi cu cmmdc=2*3*5

    ///retinem factorii primi din descompunerea celor n numere in l
    ///vom lua toate nr p ce au fact primi maxim la puterea 1 si in fct de nr de fact primi vom aduna/scadea x[nr] la rezultat
    for(i=1; i<=n; i++)
        descomp(a[i]);
    for(i=1; i<=maxi; i++)
       if(viz[i]) {nrell++; l[nrell]=i;}

    nrs=(1<<nrell)-1;
    for(i=1; i<=nrs; i++)
    {
        nr=0;
        p=1;
        for(bit=0; (1<<bit)<=i; bit++)
            if((1<<bit)&i)
        {
            p*=l[bit+1];
            nr++;
        }
        if(nr%2==1) rasp+=x[p];
        else rasp-=x[p];
    }

    f2<<(long long int)n*(n-1)/2- rasp;
    return 0;
}