Cod sursa(job #2158736)

Utilizator lixiLixandru Andrei lixi Data 10 martie 2018 15:49:55
Problema Principiul includerii si excluderii Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <iostream>
#include<fstream>
using namespace std;
ifstream f("pinex.in");
ofstream g("pinex.out");
int M, pr[79000], nr, x[50], k;
long long rez, A, B, divs[50];
bool v[1000005];
void ciur(long long n)
{
    int i, j;
    v[0] = 1;
    v[1] = 1;
    for(i = 4; i <= n; i += 2)
        v[i] = 1;
    for(i = 3; i * i <= n; i += 2)
    {
        if(v[i] == 0)
            for(j = i * i; j <= n; j += i)
                v[j] = 1;
    }
    pr[1] = 2;
    nr = 1;
    for(int i = 3; i <= n; i += 2)
        if(v[i] == 0)
            pr[++nr] = i;
}
void afis(int n)
{
    int semn = 1;
    long long p = 1;
    for(int i = 1; i <= n; i++)
        if(x[i] == 1)
        {
            semn *= -1;
            p *= divs[i];
        }
    rez += semn * A / p;
}
void back1(int n)
{
    k = 1;
    x[1] = -1;
    while(k > 0)
        if(x[k] < 1)
        {
            x[k]++;
            if(k == n)
                afis(n);
            else
            {
                k++;
                x[k] = -1;
            }
        }
        else
            k--;
}

void solutie()
{
    int poz = 0;
    for(int ind = 1; ind <= nr && 1LL * pr[ind]*pr[ind] <= B; ind++)
        if(B % pr[ind] == 0)
        {
            divs[++poz] = pr[ind];
            do
            {
                B /= pr[ind];
            }
            while(B % pr[ind] == 0);
        }
    if(B > 1)
    {
        divs[++poz] = B;
    }
    rez = 0;
    back1(poz);
}
int main()
{
    f >> M;
    ciur(1000000);
    for(int i = 1; i <= M; i++)
    {
        f >> A >> B;
        if(B == 1)
            rez = A;
        else
            solutie();
        g << rez << '\n';
    }
    return 0;
}