Cod sursa(job #542024)

Utilizator nandoLicker Nandor nando Data 25 februarie 2011 18:23:53
Problema Principiul includerii si excluderii Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include <fstream>
#include <bitset>
#include <vector>
using namespace std;

fstream fin ("pinex.in", ios::in);
fstream fout ("pinex.out", ios::out);

typedef long long int64;

//<ciur>
#define MAXP 1000010
#define NUMP 80000
bitset <MAXP> p;
int64 prim[NUMP], np = 0;

void ciur ()
{
	for (int i = 1; ((i * i) << 1) + (i << 1) < MAXP; ++i) {
		if (!p[i]) {
			for (int j = ((i * i) << 1) + (i << 1); (j << 1) + 1 <= MAXP; j += (i << 1) + 1) {
				p[j] = true;
			}
		}	
	}
	
	prim[0] = 2; np++;
	for (int i = 1; (i << 1) < MAXP; ++i) {
		if (!p[i]) {
			prim[np++] = (i << 1) + 1;
		}
	}
}
//</ciur>

int do_test ()
{
	int64 a, b;
	fin >> a >> b;
		
	vector<int> fp;
	
	int d = 0;
	while (b > 1) {
		if (b % prim[d] == 0) {
			fp.push_back (prim[d]);
			
			while (b % prim[d] == 0) {
				b /= prim[d];	
			}	
		}	
		if (prim[d] * prim[d] > b && b > 1) {
			fp.push_back (b);
			break;
		}
		
		++d;
	}
	
	int n = fp.size (), sol = a;
	
	for (int i = 1; i < (1 << n); ++i) {
		int64 nr = 1, nf = 0;
		
		for (int k = 0; k < n; ++k) {
			if (i & (1 << k)) {
				nr *= fp[k];
				++nf;	
			}
		}	
		
		if (nf & 1) {
			sol -= a / nr;	
		} else {
			sol += a / nr;
		}
			
	}
	
	return sol;
}

int main ()
{
	ciur ();
	
	int m;
	fin >> m;
	
	while (m--) {
		fout << do_test () << endl;	
	}
	
	fin.close ();
	fout.close();
	return 0;
}