Cod sursa(job #1693366)

Utilizator llalexandruLungu Alexandru Ioan llalexandru Data 22 aprilie 2016 22:54:52
Problema Fractii Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.56 kb
#include <fstream>
#include <vector>
#include <cmath>
#define NM 1000005

using namespace std;

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

int n;
bool Prim[NM];
long long F[NM];
long long S[NM];
vector <int> P;

void GenCiur()
{
    int i, j, lim;
    P.push_back(2);
    for (i=3; i<=n; i+=2)
    {
        if (Prim[i]==0)
        {
            P.push_back(i);
            for (j=i; j<=n; j+=2*i)
                Prim[j]=1;
        }
    }
}

void Euler(int lv, int p)
{
    long long i, a, j, act=1;
    if (p<=n)
    {
        if (lv==0)
        {
            if (S[p]==0)
            {
                S[p]=1;
                for (i=0; i<P.size(); i++)
                {
                    a=1;
                    for (j=1; j<=F[i]; j++)
                        a *= P[i];
                    S[p] *= S[a];
                }
            }
            F[lv]++;
            Euler(lv, p*P[lv]);
            F[lv]--;
        }
        else
        {
            Euler(lv-1, p);
            while (p*act<=n)
            {
                F[lv]++;
                act *= P[lv];
                Euler(lv-1, p*act);
            }
            F[lv]=0;
        }
    }
}

long long sol;

int main()
{
    long long i, j;
    fin>>n;
    GenCiur();
    int sz=P.size();
    for (i=0; i<sz; i++)
    {
        for (j=P[i]; j<=n; j*=P[i])
        {
            S[j]=(j/P[i])*(P[i]-1);
        }
    }
    Euler(sz-1, 1);
    for (i=2; i<=n; i++)
        sol+=S[i];
    fout<<2*sol+1;
    return 0;
}