Cod sursa(job #1251574)

Utilizator felixiPuscasu Felix felixi Data 29 octombrie 2014 17:54:04
Problema Principiul includerii si excluderii Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
//  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;
}