Pagini recente » Cod sursa (job #1448715) | Cod sursa (job #2564082) | Cod sursa (job #582777) | Cod sursa (job #2090546) | Cod sursa (job #2286134)
#include <cstdio>
#include <vector>
#include <cstdint>
#include <climits>
#define NMAX 1000000
static size_t sol[NMAX];
static unsigned char sieve[NMAX / CHAR_BIT];
static std::vector<int64_t> b_divs;
static int64_t a;
static void recurse(size_t lvl, size_t n, int64_t *acc)
{
size_t i;
int64_t result = 1;
if (lvl == n) {
for (i = 0; i < n; i++) {
result *= b_divs[sol[i]];
}
if (n & 1) {
*acc += a / result;
} else {
*acc -= a / result;
}
} else {
for (i = lvl == 0 ? 0 : sol[lvl - 1] + 1; i < b_divs.size(); i++) {
sol[lvl] = i;
recurse(lvl + 1, n, acc);
}
}
}
int main(void)
{
int m;
size_t i, j;
int64_t b, acc;
std::vector<int64_t> primes;
for (i = 2; i <= NMAX; i++) {
if ((sieve[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0) {
primes.push_back(i);
for (j = 2; i * j <= NMAX; j++) {
sieve[(i * j) / CHAR_BIT] |= 1 << ((i * j) & (CHAR_BIT - 1));
}
}
}
freopen("pinex.in", "r", stdin);
freopen("pinex.out", "w", stdout);
scanf("%d", &m);
while (m--) {
scanf("%lld %lld", &a, &b);
b_divs.clear();
j = 0;
while (j < primes.size() && primes[j] <= b && b > 1) {
if (b % primes[j] == 0) {
b_divs.push_back(primes[j]);
while (b % primes[j] == 0) {
b /= primes[j];
}
}
j++;
}
if (b > 1 && b <= a) {
b_divs.push_back(b);
}
acc = 0;
for (i = 1; i <= b_divs.size(); i++) {
recurse(0, i, &acc);
}
printf("%llu\n", a - acc);
}
return 0;
}