Cod sursa(job #3359055)

Utilizator mariusn01Marius Nicoli mariusn01 Data 23 iunie 2026 15:09:50
Problema Mins Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.75 kb

/**
Punctele (a,b) si (a*x, b*x) sunt rezolvate de aceeasi dreapta.
Rezulta ca ne intereseaza punctele de forma (a,b) cu a si b prime intre ele.
fin>>c>>d;
c--;
d--;
solutie = numarul de perechi de forma
(a,b)
- cu a cuprins intre 1 si c
- cu b cuprins intre 1 si d
- a si b prime intre ele

for (a=1;a<=c;a++)
    for (b=1;b<=d;b++) {
        while () { /// de la cmmdc cu euclid intre a si b

        }
    }
**/
/**
sol = c*d; /// mnumarul de candidati

Intrebare:
Cate dinre cele c*d puncte sunt rele din cauza lui 2 ?
R: (c/2) * (d/2)
La general, din cauza lui x sunt rele
   (c/x) * (d/x)
Notam f(x) = (c/x) * (d/x)
c = 9
d = 12
  1 2 3 4 5 6 7 8 9 10 11 12
1
2   2   2   2   2    2     2
3     3     3     3        3
4   2   2   2   2    2     2
5
6   2 3 2   23  2 3  2     23
7
8   2   2   2   2    2     2
9     3     3      3       3
sol -= (f(2) + f(3) + f(5) + f(7))
sol += (f(2*3) + f(2*5) + f(2*7) + f(3*5) + f(3*7) + f(5*7))

sol += (suma din valori f(un singur numar prim))
sol -= (suma din valori f(produs de 2 numere prime distincte))
sol += (suma din valori f(produs de 3 numere prime distincte))
sol -= (suma din valori f(produs de 4 numere prime distincte))
**/
#include <fstream>
using namespace std;

long long c, d, sol, i, j, m;

long long f(long long x) {
    return (c/x) * (d/x);
}

long long ciur[1000010], ciur1[1000010];


int main () {
    ifstream fin ("mins.in");
    ofstream fout("mins.out");

    fin>>c>>d;
    c--;
    d--;
    m = min(c,d);

    for (i=2;i<=m;i++)
        if (ciur[i] == 0)
            for (j=i;j<=m;j+=i)
                ciur[j] ++; /// socotesc pe i ca factor prim al lui j
    /// deci obtin ciur[i] = cati factori primi are numarul i

    for (i=2;i<=m;i++)
        if (ciur1[i] == 0)
            for (j=i*i;j<=m;j+=i*i)
                ciur1[j] = 1; /// matchez cu 1 numere divizinile printr-un patrat perfect
    /**
    numerele rele sunt cele care au cel putin un factor prim la o putere mai mare ca 1
    de exemplu 24 = 2^3 * 3 dar acest numar este divizibil prin 2*2
    numerele rele sunt cele divizibile printr-un patrat perfect
    **/
    sol = c*d;

    for (i=2;i<=m;i++)
        if (ciur1[i] == 0) /// i este produs de numere prime distincte
            if (ciur[i] % 2 == 1)
                sol -= f(i);
            else
                sol += f(i);
/**
    2  sol-=f(2)
    3  sol-=f(3)
    4  nu ma intereseaza
    5  sol-=f(5)
    6  sol+=f(6) pentru ca 6 = 2*3
    7  sol-=f(7)
    8  nu ma intereseaza
    9  nu ma intereseaza
    ... daca min(c,d era mai mare)
    15 sol += f(15)    15 = 3*5
    19 sol-=f(19)
    20 nimic
    21 sol += f(21)    21 = 3*7
    ...
    30 sol -= f(30)   30=2*3*5
**/
    fout<<sol;
}