Cod sursa(job #2354140)

Utilizator Andreea100Andreea P Andreea100 Data 24 februarie 2019 21:50:39
Problema Fractii Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.79 kb
#include <fstream>
#define SIZE 1000000
using namespace std;
ifstream cin("fractii.in");
ofstream cout("fractii.out");

short p[SIZE+10], pi[SIZE+10];
int phi[SIZE + 10];

int main()
{
    int n;
    int i, j;
    cin >> n;
    p[1] = 0;
    p[2] = 1;
    // numerele pare nu sunt prime
    // printre numerele impare sunt si numere prime
    for (i = 3; i <= n; i+=2)
    {
        p[i]=1;
    }
    // implementam ciurul lui eratostene

    for (i = 3; i * i <= n; i++)
    {
        if (p[i]==1) {
            for (j = 2 * i; j <= n; j+=i)
                p[j] = 0;
        }
    }
    // generam vectorul pi
    phi[1] = 0;
    for (i = 2; i <= n; i ++)
    {
        if (p[i]==1) {
            //daca i este prim pi(n)=n-1
            phi[i] = i - 1;
            pi[i] = 1;

            //puterile lui i
            for (long long j = i; j * i <= n; j *= i)
            {
                phi[i * j] = j * phi[i];
                pi[i * j] = 1;
            }

        }else{
            if(!pi[i]){
                //daca i este compus pi(n)=pi(a)*pi(b)
                int d = 2;
                //gasim cel mai mic divizor prim al numarului
                while (i%d) {
                    d++;
                }
                int a, b = i;
                //pe care il extragem la maxim
                while (b%d==0) {
                    b /= d;
                }
                a = i / b;
                //avem garantia ca a si b vor fi prime intre ele conform acestei strategii
                phi[i] = phi[a] * phi[b];
                pi[i] = 1;
            }
        }

    }

    long long s = 0;
    for (i = 2; i <= n; i++)
    {
        s += phi[i];
    }
    cout << 2*s+1;

    cin.close();
    cout.close();
    return 0;
}