Cod sursa(job #1533592)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 22 noiembrie 2015 19:17:16
Problema Pairs Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <bits/stdc++.h>

using namespace std;

const int kMaxValue = 1e6;

int main(void) {
  ifstream in("pairs.in");
  ofstream out("pairs.out");
  int N;

  in >> N;
  vector <int> V(N);
  for (int i = 0; i < N; i++)
    in >> V[i];
  in.close();

  vector <int> lp(kMaxValue + 1);
  auto sieve = [&lp] (const int &N) -> void {
    for (int i = 2; i <= N; i++) {
      if (!lp[i]) {
        lp[i] = i;
        for (int j = i + i; j <= N; j += i) {
          if (!lp[j]) {
            lp[j] = i;
          }
        }
      }
    }
  };

  sieve(kMaxValue);

  vector <int> freq(kMaxValue + 1, 0);
  for (int i = 0; i < N; i++) {
    int x = V[i];
    vector <int> divisors;
    while (x > 1) {
      while (lp[x] == lp[x / lp[x]]) {
        x /= lp[x];
      }
      divisors.emplace_back(lp[x]);
      x /= lp[x];
    }
    int k = (int) divisors.size();
    for (int i = 0; i < (1 << k); i++) {
      int setBits = 0;
      int product = 1;
      for (int j = 0; j < k; j++) {
        if ((i >> j) & 1) {
          product *= divisors[j];
          setBits++;
        }
      }
      if (setBits & 1) {
        freq[product]--;
      } else {
        freq[product]++;
      }
    }
  }

  long long answer = 1LL * N * (N + 1) / 2LL;
  for (int i = 2; i <= kMaxValue; i++) {
    if (freq[i] != 0) {
      if (freq[i] < 0) {
        freq[i] = -freq[i];
        answer -= 1LL * freq[i] * (freq[i] + 1) / 2LL;
      } else {
        answer += 1LL * freq[i] * (freq[i] + 1) / 2LL;
      }
    }
  }
  out << answer << '\n';
  out.close();
  return 0;
}