Cod sursa(job #2972174)

Utilizator alexscanteieScanteie Alexandru alexscanteie Data 28 ianuarie 2023 19:12:53
Problema Pairs Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <fstream>
using namespace std;

ifstream fin("pairs.in");
ofstream fout("pairs.out");
#define N 100050

int lpf[N], mobius[N],a[N];

// Function to calculate least
// prime factor of each number
void least_prime_factor()
{
    for (int i = 2; i < N; i++)

        // If it is a prime number
        if (!lpf[i])

            for (int j = i; j < N; j += i)

                // For all multiples which are not
                // visited yet.
                if (!lpf[j])
                    lpf[j] = i;
}

// Function to find the value of Mobius function
// for all the numbers from 1 to n
void Mobius()
{
    for (int i = 1; i < N; i++) {

        // If number is one
        if (i == 1)
            mobius[i] = 1;
        else {

            // If number has a squared prime factor
            if (lpf[i / lpf[i]] == lpf[i])
                mobius[i] = 0;

            // Multiply -1 with the previous number
            else
                mobius[i] = -1 * mobius[i / lpf[i]];
        }
    }
}

// Function to find the number of pairs
// such that gcd equals to 1
int gcd_pairs(int a[], int n)
{
    // To store maximum number
    int maxi = 0;

    // To store frequency of each number
    int fre[N] = { 0 };

    // Find frequency and maximum number
    for (int i = 0; i < n; i++) {
        fre[a[i]]++;
        maxi = max(a[i], maxi);
    }

    least_prime_factor();
    Mobius();

    // To store number of pairs with gcd equals to 1
    int ans = 0;

    // Traverse through the all possible elements
    for (int i = 1; i <= maxi; i++) {
        if (!mobius[i])
            continue;

        int temp = 0;
        for (int j = i; j <= maxi; j += i)
            temp += fre[j];

        ans += temp * (temp - 1) / 2 * mobius[i];
    }

    // Return the number of pairs
    return ans;
}

int main()
{
    fin>>n;
    for(int i=1;i<=n;i++){
        fin>>a[i];
    }
    cout << gcd_pairs(a, n);

    return 0;
}

/*int main(){
    int n,cnt=0;
    fin>>n;
    for(int i=1;i<=n;i++){
        fin>>a[i];
    }
    for(int i=1;i<n;i++){
        for(int j=i+1;j<=n;j++)
            if(gcd(a[i],a[j])==1)
                cnt++;
    }
    fout<<cnt;
    return 0;
}*/