Cod sursa(job #1978902)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 9 mai 2017 02:27:28
Problema Principiul includerii si excluderii Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
typedef long long LL;

#ifdef INFOARENA
#define ProblemName "pinex"
#endif

#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "fis.in"
#define OuFile "fis.out"
#endif

#define MAXN 1000010
int physical[(MAXN >> 6) + 1];
int primes[MAXN / 2], pnr;

inline int getp(int n) {
	return physical[n >> 6] & (1 << ((n >> 1) & 31));
}

inline void setp(int n) {
	physical[n >> 6] |= (1 << ((n >> 1) & 31));
}

void ciur() {
	pnr = 0;
	memset(physical, 0, sizeof(physical));
	primes[pnr++] = 2;
	int SQLIM = (int)sqrt(MAXN) + 1;
	for (int d = 3; d < SQLIM; d += 2) {
		if (getp(d)) continue;
		primes[pnr++] = d;
		for (int i = d * d, k = d * 2; i < MAXN; i += k)
			setp(i);
	}
	for (int d = SQLIM; d < MAXN; ++d)
	if (!getp(d))
		primes[pnr++] = d;
}

#define MAXDIVS 100
LL divs[MAXDIVS], dnr;

LL solve(LL A, LL B) {
	dnr = 0;
	for (int i = 0; i < pnr; ++i) {
		int p = primes[i];
		if (1LL * p * p > B) break;
		if (B % p == 0)
			divs[dnr++] = p;
		while (B % p == 0)
			B /= p;
	}
	if (B > 1)
		divs[dnr++] = B;
	LL ans = 0;
	int lim = 1 << dnr;
	for (int mask = 1; mask < lim; ++mask) {
		int cnt = 0;
		LL prod = 1;
		for (int i = 0; i < dnr; ++i)
		if (mask & (1 << i)) {
			++cnt;
			prod *= divs[i];
		}
		if (cnt & 1)
			ans += A / prod;
		else ans -= A / prod;
	}
	return ans;
}

int main() {
	assert(freopen(InFile, "r", stdin));
	assert(freopen(OuFile, "w", stdout));
	ciur();
	int M;
	scanf("%d", &M);
	while (M--) {
		LL A, B;
		scanf("%lld%lld", &A, &B);
		printf("%lld\n", A - solve(A, B));
	}
	return 0;
}