Pagini recente » Solutii preONI 2007, Runda 3 | Cod sursa (job #640768) | Cod sursa (job #2428924) | Cod sursa (job #2792543) | Cod sursa (job #1251574)
// InfoArena ~~ Pinex
#include <fstream>
#include <cmath>
using namespace std;
ifstream in("pinex.in");
ofstream out("pinex.out");
const int NMAX = 1000000;
const int P_MAX = 200000;
int p[P_MAX+1]; /// Tin divizorii primi ai lui Y
bool ciur[NMAX+3];
int pr[P_MAX+1], pr_count= 0; /// Tin numerele prime
long long A,B;
void ciurul() {
int lim= 1000;
for( int i= 4; i<=NMAX; i+= 2 ) ciur[i]= 1;
for( int i= 3; i<=lim; i+= 2 ) {
if( !ciur[i] ) {
for( int j= i*i; j<=NMAX; j+= 2*i ) ciur[j]= 1;
}
}
pr[ ++pr_count ]= 2;
for( int i= 3; i<=NMAX; i+= 2 ) {
if( !ciur[i] ) pr[ ++pr_count ]= i;
}
}
int Desc_factori( int N ) {
int R= 0, ind= 1;
int lim= (int)sqrt( 1.0*N );
bool ok= 0;
while( N>1 && pr[ind]<=lim ) {
ok= 0;
while( N%pr[ind] == 0 ) {
N/= pr[ind];
ok= 1;
}
if( ok ) {
p[ ++R ]= pr[ind];
lim= (int)sqrt( 1.0*N );
}
++ind;
}
if( N>1 ) p[ ++R ]= N;
return R;
}
long long PINEX( long long X, long long Y ) {
long long Sol= 0;
int nr= Desc_factori( Y );
int k= 1<<nr;
for( int i= 1; i<k; ++i ) {
int cnt= 0, prod= 1;
for( int j= 0; j<nr; ++j ) {
if( i & (1<<j) ) {
++cnt;
prod*= p[ j+1 ];
}
}
if( cnt%2 == 1 ) { /// Adun divizorii
Sol+= X/prod;
}
else { /// Scad divizorii
Sol-= X/prod;
}
}
return X-Sol;
}
int main() {
ciurul();
int T;
in >> T;
for( int t= 0; t<T; ++t ) {
in >> A >> B;
out << PINEX( A, B ) << '\n';
}
return 0;
}