Cod sursa(job #705833)

Utilizator IronWingVlad Paunescu IronWing Data 5 martie 2012 00:06:25
Problema Fractii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <stdio.h>

/*
  In number theory, Euler's totient or phi function, phi(n) is an arithmetic function that counts the number
  of positive integers less than or equal to n that are relatively prime to n. 
*/
/* function which uses the Prime Sieve of Eratosthenes to compute the totient function */
void computeTotient(const int n, int *tot){
	int i, j;
	for(i = 1;i<=n; ++i){
		/*first, set the totient function as if all numbers are prime */
		tot[i] = i-1;
	}
	for(i = 2; i<=n; ++i){
		/* for each number */
		for(j = 2 * i; j<=n; j += i){
			/* for all non prime numbers (multiples), adjust the totient*/
				tot[j] -= tot[i]; // decrease by the number of totient(i)
		}
	}
}

/* another better function which uses Prime Sieve of Eratosthenes to compute the totient function,
   and also the formula tot(n) = n * product over the prime divisors p of n of [( p-1) / p]
*/
void computeTotientForm(const int n, int *tot){
	int i, j;
	for(i = 1; i <= n; ++i){
		/*first, set the totient function tot(i) = i, 
		also indicates prime number (initially all numbers in the sieve are prime) */
		tot[i] = i;
	}

	for(i = 2; i <= n; ++i){
		/* for each number */
		if(tot[i] == i){
			/* if the number is prime, then it is a prime divisor of ohter numbers */
			for(j = i; j<=n; j+=i){
				/* for each multiple of the prime i, including i: tot[j] = tot[j] * (i-1)/i */
				tot[j] /= i, tot[j] *= (i-1);
			}
		}
	}
}

/*  function which counts the number of irreducible fractions that can form with numbers <=n.
	It uses totient function to accomplish that.
*/
long long countFractions(const int n, int *tot){
	long long count = 0; // initially 0 fractions
	int i;
	for(i=2; i<=n; ++i){
		/* sum the totients - irreducible functions */
		count += tot[i];
	}
	/*add 1, to count for 1/1, and 2 times because for the irreducible fraction a/b, we also have b/a */
	return 1 + 2 * count; 
}

int main(){	
	freopen("fractii.in","r", stdin);
	freopen("fractii.out","w", stdout);
	int n;
	int *tot;
	scanf("%d", &n);
	fclose(stdin);
	tot = new int[n+1](); // allocate memory for the totient function
	computeTotientForm(n, tot);
	long long fractions = countFractions(n, tot);	
	printf("%lld", fractions);
	delete [] tot;
	fclose(stdout);
	return 0;
}