Cod sursa(job #2574432)

Utilizator bogdanvladmihaiBogdan Vlad-Mihai bogdanvladmihai Data 5 martie 2020 22:13:48
Problema Principiul includerii si excluderii Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.34 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("pinex.in");
ofstream fout("pinex.out");

typedef long long ll;

const int MAX_N = 1e6 + 5;

int m;

ll a, b;

vector <int> p;
bitset <MAX_N> sieve;

ll count_prime(ll a, ll b) {
  vector <ll> fct;
  ll ans, subset;
  int d, limit, card;
  d = 0;
  while (p[d] * p[d] <= b) {
    if (b % p[d] == 0) {
      fct.push_back(p[d]);
      while (b % p[d] == 0) {
        b /= p[d];
      }
    }
    ++d;
  }
  if (b > 1) {
    fct.push_back(b);
  }
  ans = 0;
  limit = (1 << fct.size());
  for (int mask = 1; mask < limit; ++mask) {
    card = 0;
    subset = 1;
    for (int i = 0; i < fct.size(); ++i) {
      if ((mask & (1 << i)) > 0) {
        ++card;
        subset = subset * fct[i];
      }
    }
    if (card % 2 > 0) {
      ans = ans + a / subset;
    } else {
      ans = ans - a / subset;
    }
  }
  return ans;
}

int main() {
  sieve[0] = sieve[1] = 1;
  for (ll i = 2; i * i < MAX_N; ++i) {
    if (sieve[i] == 0) {
      for (ll j = i * i; j < MAX_N; j += i) {
        sieve[j] = 1;
      }
    }
  }
  for (int i = 2; i < MAX_N; i += 1 + (i % 2)) {
    if (sieve[i] == 0) {
      p.push_back(i);
    }
  }
  fin >> m;
  while (m --) {
    fin >> a >> b;
    fout << a - count_prime(a, b) << "\n";
  }
  return 0;
}