Cod sursa(job #195850)

Utilizator andrei.ismailIsmail Andrei-Adnan andrei.ismail Data 22 iunie 2008 11:30:36
Problema Fractii Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 1.25 kb
#include <stdio.h>
#include <string.h>

#define MAX 1000001
int cache[MAX]; /* Coprime caching */
int firstdiv[MAX]; /* First prime divisor of each number */

/* Generate the first divisor for each number n */
void gen_firstdiv(int n) {
	int i, j;

	memset(firstdiv, 0, (n + 1)* sizeof(int));
	for (i = 2; i <= n / 2; i++) 
		if (firstdiv[i] == 0) {
		for (j = 2 * i; j <= n; j += i)
			if (firstdiv[j] == 0)
				firstdiv[j] = i;
	}
}

/* Return the number of coprime numbers < n. */
int coprimes(int n) {
	int factor = 1, d = firstdiv[n];

	if (d != 0) {
		while (n % d == 0) {
			n /= d;
			factor *= d;
		}
		return (factor - factor/d) * cache[n];
	} else
		return n-1;
}

/* Generate coprimes for each number <= n */
void gen_coprimes(int n) {
	int i;

	cache[1] = 1;
	cache[2] = 1;
	cache[3] = 2;
	for (i = 4; i <= n; i++)
		cache[i] = coprimes(i);
}

int main(void) {
	FILE *fin, *fout;
	int n, i;
	long long result = 0;

	fin = fopen("fractii.in", "rt");
	fscanf(fin, "%d\n", &n);
	fclose(fin);

	gen_firstdiv(n);
	gen_coprimes(n);

	result = 1;
	for (i = 2; i <= n; i++) {
		result += 2 * cache[i];
	}

	fout = fopen("fractii.out", "wt");
	fprintf(fout, "%lld\n", result);
	fclose(fout);
	return 0;
}