Cod sursa(job #200119)

Utilizator tomescu_alinTomescu Alin tomescu_alin Data 22 iulie 2008 12:55:02
Problema Fractii Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.67 kb
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

unsigned int * eratosthenesSieve (unsigned int n) {
	unsigned int * sieve = new unsigned int[n+1];
    
	memset (sieve, 1, (n+1) * sizeof(unsigned int));
	sieve[1] = 0;
	sieve[0] = 0;
	
	for (unsigned int i = 2; i*i <= n; i += 1) {
		if (sieve[i]) {
			unsigned int j = 2;
			while (i*j <= n) {
				sieve[i*j] = 0;
				j++;
			}
		}
	}
	return sieve;
}

unsigned int * generateTotients (unsigned int n)
{
	unsigned int * sieve = eratosthenesSieve (n);
	
	unsigned int * totient = new unsigned int[n+1];
	//memset (totient, 0, (n+1) * sizeof (unsigned int));
	
	for (int i = 2; i <= n; i++)
	{
		if (sieve[i])
			totient[i] = i-1;
		else {
			//cout << "i = " << i << endl;
			totient[i] = i;
			double product = 1.0;
			for (int j = 2; j < i; j++)
			{
				//cout << "\tj = " << j << " ";
				if (sieve[j] && i%j == 0) {
					product *= (1.0-(1.0/(double)j));
					//cout << "\t\tproduct = " << product;
				}
				//cout << endl;
			}
			totient[i] = floor((double)totient[i] * product);
		}
	}
	delete[] sieve;
	return totient;
}

bool isPrime (unsigned int n)
{
	for (int i = 2; i <= sqrt(n); i++)
	{
		if (n%i == 0)
			return false;
	}
	return true;
}

int main()
{
	unsigned int n;
	ifstream fin ("fractii.in");
	fin >> n;
	fin.close();
	
	unsigned int * totient = generateTotients (n);
	long total = 1;
	
	for (int i = 2; i <= n; i++)
	{
		total += totient [i] * 2;
		//cout << "tot(" << i << ")=" << totient[i] << endl;
	}
	
	ofstream fout ("fractii.out");
	fout << total;
	//cout << total;
	fout.close();
	
	delete[] totient;
	return 0;
}