Cod sursa(job #200424)

Utilizator tomescu_alinTomescu Alin tomescu_alin Data 23 iulie 2008 21:22:18
Problema Fractii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.88 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 (unsigned int i = 2; i <= n; i++)
	{
		if (totient[i])
			continue;
			
		if (sieve[i]) {
			totient[i] = i-1;
			unsigned int result = i;
			while ((result *= i) <= n)
			{
				totient[result] = result/i * (i-1);
			}
		}
		else {
			//cout << "i = " << i << endl;
			totient[i] = i;
			double product = 1.0;
			for (unsigned 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] = (unsigned int)ceil((double)totient[i] * product);
			
			unsigned int result = i;
			while ((result *= i) <= n)
			{
				totient[result] = result/i * totient[i];
			}
		}
	}
	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;
}*/

// n = suma (totient[i]) unde i il divide pe n...
// totient[i] = i-1 daca i este prim
// deci max(totient[i]) oricare ar fi i din N este i-1
// deci putem calcula totient[i] scazand din i-1 toti totient[d] unde d il divide pe i (inclusiv d=1 si d=8)

/* Ex:
8 = tot(1) + tot(2) + tot(4) + tot(8) => tot(8) = 8-1 - (tot(2)+tot(4))
6 = tot(1) + tot(2) + tot(3) + tot(6) => tot(6) = 6-1 - (tot(2)+tot(3))
5 = tot(1) + tot(5) => tot(5) = 5-1 (5 e prim)
4 = tot(1) + tot(2) + tot(4) => tot(4) = 4-1 - tot(2)
3 = tot(1) + tot(3) => tot(3) = 3-1 (3 e prim)
2 = tot(1) + tot(2) => tot(2) = 2-1 (2 e prim)
*/
unsigned int * generateTotients (unsigned int n)
{
	unsigned int * totient = new unsigned int[n+1];
	
	for (int i = 2; i <= n; ++i)
		totient[i] = i-1;
		
	for (int i = 2; i <= N; ++i)
		for (int j = 2 * i; j <= n; j += i)
			totient[j] -= totient[i];
			
	return totient;
}

int main()
{
	unsigned int n;
	ifstream fin ("fractii.in");
	fin >> n;
	fin.close();
	
	unsigned int * totient = generateTotients (n);
	long total = 1;
	
	for (unsigned 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;
}