Cod sursa(job #3291919)

Utilizator szaszgeri94Szasz Gergely szaszgeri94 Data 6 aprilie 2025 11:44:46
Problema Principiul includerii si excluderii Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <iostream>
#include <fstream>
    
using namespace std;
using ll = long long;

ifstream fin("pinex.in");
ofstream fout("pinex.out");

const int nmax = 1e6;
const int kmax = 999000;

int n, k, divs[kmax + 5], fac[kmax + 5];
ll x, y;
bool v[nmax+5];

/* 1 <= y <= 10^12

10^12-nek legnagyobb osztoja sqrt(10^12) = 10^6 lehet, tehat az osszes primszamot 
megkeressuk addig.

*/

void debug(){
    cout << "DEBUG" << '\n';
}

void solve(){
    fin >> x >> y;
    ll res = x;

    int d = 0, t = 0;

    // Bontsuk fel y-t primtenyezokre

    while(y > 1){
        if(y % divs[d] == 0){
            fac[t++] = divs[d];
            while(y % divs[d] == 0)
                y /= divs[d];
        }
        if(y > 1 && divs[d] * divs[d] > y){ // y prim
            fac[t++] = y;
            y = 1;
        }
        d++;
    }   

    for(int i = 1; i < (1 << t); i++){
        int cnt = 0;
        ll prod = 1;
        for(int j = 0; j < t; j++){
            if(i & (1 << j)){
                prod = 1LL * prod * fac[j];
                cnt++;
            }
        }
        if(cnt % 2) cnt = -1;
        else cnt = 1;

        res = res + 1LL * cnt * x / prod;

    }
    fout << res << '\n';

}

void precompute(){
    v[0] = 1;
    v[1] = 1;
    for(int i = 2; i*i <= nmax; i++)
        if(v[i] == 0)
            for(int j = i*i; j <= nmax; j += i)
                v[j] = 1;
    k = 0;
    for(int i = 2; i <= nmax; i++)
        if(v[i] == 0)
            divs[k++] = i;
}

int main()
{
    fin >> n;
    precompute();
    while(n--)
        solve();
    
    return 0;
}