Cod sursa(job #55849)

Utilizator chermanCorina Herman cherman Data 28 aprilie 2007 15:01:02
Problema Fractii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.5 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};
int tot(int x)
{
    if ( totv[x] != 0 )
       return totv[x];

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

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

    int cnt = 0;
    int d=0;
    int pp=pr[i]-1;
    while ( p % pr[i] == 0 )
    {
        p /= pr[i];
        if(cnt==0) d=p;
        ++cnt;
    }

    if ( p == 1 )
        totv[x] = pp*d;
    else
    {
        //int g = x / (int)pow(pr[i], cnt);
        //int g = p;
        totv[x] = pp*(d/p)*totv[p];
    }

    return totv[x];
}
double rapprim[78500];
int cntprime = 1;

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

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

int totcorina(int nr)
{
    double t=nr;
    int i = 0;

    while ( i<cntprime && pr[i] < nr )
    {
        if ( nr % pr[i] == 0 )
          {
            t*=rapprim[i];
          }
        ++i;
    }
   if (pr[i]==nr)
            t*=rapprim[i];

    return (int)t;
}
int main()
{
//    11 -> 83
//    15 -> 143
//    31 -> 615
//    99 -> 6007
//    100 -> 6087
//    1000000 -> 607927104783

    in >> n;
    //n=1000000;

    //prime();
    primec();

    long long sol = 0;

    //cout << tot(12) << endl;

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

    out << (sol*2 + 1) << endl;



	return 0;
}