Cod sursa(job #1693377)

Utilizator llalexandruLungu Alexandru Ioan llalexandru Data 22 aprilie 2016 23:12:28
Problema Fractii Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.46 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;
    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(long long lv, long long p, long long acm)
{
    long long i, a, j, act=1;
    if (p<=n)
    {
        if (lv==0)
        {
            if (S[p]==0)
            {
                a=1;
                for (i=1; i<=F[0]; i++)
                    a *= 2;
                S[p] = acm*S[a];
            }
            F[lv]++;
            Euler(lv, p*P[lv], acm);
            F[lv]--;
        }
        else
        {
            while (p*act<=n)
            {
                F[lv]++;
                Euler(lv-1, p*act, acm*S[act]);
                act *= P[lv];
            }
            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);
        }
    }
    S[1]=1;
    Euler(sz-1, 1, 1);
    for (i=2; i<=n; i++)
        sol+=S[i];
    fout<<2*sol+1;
    return 0;
}