Cod sursa(job #54643)

Utilizator DastasIonescu Vlad Dastas Data 25 aprilie 2007 12:58:29
Problema Fractii Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <iostream>
#include <fstream>
#include <math.h>

using namespace std;

ifstream in("fractii.in");
ofstream out("fractii.out");

int n;
int pr[78500];

void prime()
{
    char a[1000000] = {0};

    int cnt = 1;
    int p = sqrt(n)+1;
    pr[0] = 2;
    for ( int i = 3; i <= n; i += 2 )
    {
        if ( a[i] == 0 )
        {
            pr[cnt++] = i;
            if ( i <= p )
            {
                for ( int j = (i<<1); j <= n; j += i )
                    a[j] = 1;
            }
        }
    }
}

int totv[1000000] = {0, 1, 1, 2, 2}; // totv[i] = tot(i)

int tot(int x)
{
//    double res = x;
//
//    for ( int i = 0; i <= x; ++i )
//        if ( pr[i] != 0 )
//        {
//            if ( x % pr[i] == 0 )
//                res = res * (1.0-(1.0/pr[i]));
//        }
//        else
//            break;
//
//    return ceil(res);

    int p = x;

    int i = 0;
    int cnt = 0;
    int gasit = 0;

    if ( totv[x] != 0 )
       return totv[x];

    while ( pr[i] < p )
    {
        if ( p % pr[i] == 0 )
        {
            gasit = 1;
            break;
        }
        ++i;
    }

    if ( !gasit )
    {
        totv[x] = x-1;
        return totv[x];
    }

    while ( p % pr[i] == 0 )
    {
        p /= pr[i];
        ++cnt;
    }

    if ( p == 1 )
        totv[x] = (pr[i]-1)*pow(pr[i], cnt-1);
    else
        totv[x] = (pr[i]-1)*pow(pr[i], cnt-1)*totv[x / (int)pow(pr[i], cnt)];

    return totv[x];
}

int main()
{
    in >> n;
    prime();

    long long sol = 0;
    int i = 0;
    char viz[1000000] = {0};

    while ( pr[i] )
        tot(pr[i]), ++i;

    i = 0;

    while ( pr[i] )
    {
        for ( int t = pr[i]; t <= n; t += pr[i] )
        {
            if ( !viz[t] )
            {
                int q = tot(t);
                //cout << t << " " << q << endl;
                sol += q;
                if ( q )
                    viz[t] = 1;
            }
        }
        ++i;
    }

//    for ( int j = 2; j <= n; ++j )
//        sol += tot(j);

    sol = sol*2 + 1;

    out << sol << endl;



	return 0;
}