Cod sursa(job #35817)

Utilizator sandyxpSanduleac Dan sandyxp Data 22 martie 2007 16:12:13
Problema Fractii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.17 kb
#include <stdio.h>
#include <string.h>

#define FIN "fractii.in"
#define FOUT "fractii.out"
#define PR_MAX 1000
#define MAXPRIME 1000
#define MAXN 1000000
#define ll long long

// pt nr prim, t(p) = p-1

int n, nr;
char P[(PR_MAX>>4) + 1];
int Prime[MAXPRIME];
ll tot[MAXN+1];

int sieve(int n) 
{
    int i, j, nr = 0;
    for (i=1; (i*i + i) << 1 <= n; ++i)
        if ((P[i>>3] & (1 << (i&7))) == 0)
            for (j=(i*i + i) << 1; (j<<1) + 1 <= n; j += (i<<1) + 1)
                P[j>>3] |= 1 << (j&7);
    Prime[nr++] = 2;
    for (i=1; (i<<1) + 1 <= n; ++i)
        if ((P[i>>3] & (1 << (i&7))) == 0) 
            Prime[nr++] = (i<<1) + 1;
    return nr;
}

int main()
{
    int i, j, x;
    ll rez = 1;
    freopen(FIN, "r", stdin);
    freopen(FOUT,"w",stdout);
    scanf("%d", &n);
    nr = sieve(PR_MAX); // sqrt(n)
    tot[1] = 1;
    for (i=2; i<=n; ++i) {
	int pow = 1;
	x = i;
	for (j=0; j<nr && pow == 1; ++j)
	    while (x % (pow*Prime[j]) == 0)
		pow *= Prime[j];
	--j;
	if (pow == 1) tot[i] = x-1; // e un sg numar prim ^1 mai mare ca sqrt(n)
	else x /= pow, tot[i] = tot[x] * (Prime[j] - 1) * pow / Prime[j];
	rez += 2 * tot[i];
    }
    printf("%lld\n", rez);
    return 0;
}