Rezolvare completă PbInfo #2241 inspectorat

Inspectoratul școlar județean organizează un concurs pentru ocuparea strategicului post de fochist. La proba de informatică, cea mai importantă a concursului, candidații au de rezolvat următoarea problemă.

Cerința

Se dau n perechi de numere naturale și pentru fiecare pereche (x,y) trebuie să se afle câte numere naturale nenule strict mai mici decât produsul x * y sunt prime cu x * y.

Date de intrare

Programul citește de la tastatură numărul n, iar apoi n perechi de numere naturale x și y.

Date de ieșire

Programul va afișa pe ecran, pentru fiecare pereche (x, y) valoarea cerută, urmată de enter.

Restricții și precizări

  • 1 ≤ n ≤ 10 000
  • Pentru fiecare pereche (x, y), 2 ≤ x, y ≤ 200 000
  • Două numere sunt prime între ele dacă cel mai mare divizor al lor este 1.
  • Atenție, produsul a două numere poate depăși valoarea maximă admisă de tipul int.
  • Această ultimă precizare este disponibilă numai inspectorilor.

Exemplu

Intrare

3
3 4
3 3
97 33

Ieșire

4
6
1920

Explicație

Pentru prima pereche: 3 * 4 = 12, iar 12 este prim cu patru numere: 1, 5, 7, 11. Pentru a doua pereche: 3 * 3 = 9, iar 9 este prim cu șase numere: 1, 2, 4, 5, 7, 8. Pentru a treia pereche: puteți verifica și singuri că așa este. Oricum, inspectorii nu greșesc niciodată.

Cum e corect?

cout < "As la info"; cout << "As la info"; cout >> "As la info";

Felicitări! Poți mai mult?

Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.

Greșit, dar nu-i bai!

Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.

Rezolvare

Iată rezolvarea de 100 de puncte pentru problema inspectorat:

#include <bits/stdc++.h>
using namespace std;

bitset<40000> b;
int n, a[3500];

void Ciur()
{
    int i, j;

    for (i = 4; i <= 32000; i += 2)
        b[i] = 1;
    for (i = 3; i * i <= 32000; i += 2)
        if (b[i] == 0)
            for (j = i * i; j <= 32000; j = j + 2 * i)
                b[j] = 1;
    a[1] = 2;
    n = 1;
    for (i = 3; i <= 32000; i += 2)
        if (b[i] == 0) a[++n] = i;
}

/// calcul Phi(x)
int Phi(int x)
{
    int i, d, phi;
    if (x == 2) return 1;
    d = 2;
    i = 1;
    phi = x;
    while (x > 1 && d * d <= x && i <= n)
    {
        if (x % d == 0)
        {
            while (x % d == 0)
                x /= d;
            phi = phi / d * (d - 1);
        }
        d = a[++i];
    }
    if (x > 1) /// x - prim
        phi = phi / x * (x - 1);
    return phi;
}

int Cmmdc(int x, int y)
{
    int r;
    while (y != 0)
    {
        r = x % y;
        x = y;
        y = r;
    }
    return x;
}

void CitireAfisare()
{
    int i, Q, x, y, d;
    long long sol;
    cin >> Q;
    for (i = 1; i <= Q; ++i)
    {
        cin >> x >> y;
        d = Cmmdc(x, y);
        sol = 1LL * Phi(x) * Phi(y) * d / Phi(d);
        cout << sol << "\n";
    }
}

int main()
{
    Ciur();
    CitireAfisare();
    return 0;
}

Atenție

Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa Adresa de email.

Rezolvarea problemei #2241 inspectorat

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #2241 inspectorat de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.

Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!