Cod sursa(job #1514177)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 30 octombrie 2015 19:48:14
Problema Pairs Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.95 kb
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

ifstream in("pairs.in");
ofstream out("pairs.out");

const int MAX_VAL = 1000000;
const int MAX_N = 100000;

vector < int > genPrimes(const int limit) {
    vector < bool > notPrime(limit + 1, 0);
    vector < int > primeList;
    int i, j;

    for(i = 2; i*i <= limit; i++) {
        for(j = i*i; j <= limit; j += i) {
            notPrime[j] = 1;
        }
    }
    for(i = 2; i <= limit; i++) {
        if(!notPrime[i]) {
            primeList.push_back(i);
        }
    }

    return primeList;
}

int countCoprime(int X, int n, vector < int > const &P, vector < int > const &nDiv) {
    vector < int > xPrimes;
    int nP, i, j, ANS = 0, sgn, pCombine;

    for(i = 0; P[i] * P[i] <= X; i++) {
        if(X % P[i] == 0) {
            xPrimes.push_back(P[i]);
            while(X % P[i] == 0) X /= P[i];
        }
    }
    if(X > 1) xPrimes.push_back(X);
    nP = xPrimes.size();

    for(i = 1; i < (1 << nP); i++) {
        pCombine = 1; sgn = -1;
        for(j = nP-1; j >= 0; j--) {
            if(i & (1 << j)) {
                pCombine *= xPrimes[j];
                sgn *= -1;
            }
        }
        ANS += sgn * nDiv[pCombine];
    }

    return  n - ANS;
}

int main() {
    long long ANS = 0;
    int n, i, j, val, maxVal;
    vector < int > P, nDiv, A;
    vector < bool > U(MAX_VAL + 1, 0);

    in >> n;
    for(i = 1, maxVal = 0; i <= n; i++) {
        in >> val;
        U[val] = 1;
        A.push_back(val);
        maxVal = max(val, maxVal);
    }

    P = genPrimes(maxVal);
    nDiv.resize(maxVal + 1);
    for(i = 2; i <= maxVal; i++) {
        for(j = i; j <= maxVal; j += i) {
            if(U[j]) {
                nDiv[i]++;
            }
        }
    }

    for(i = 0; i < n; i++) {
        ANS += countCoprime(A[i], n, P, nDiv);
    }

    out << ANS / 2 << '\n';
    return 0;
}