Cod sursa(job #480483)

Utilizator dcm9000Dinu Cristian Mircea - UPB dcm9000 Data 28 august 2010 04:06:50
Problema Fractii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.34 kb
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>

using namespace std;

#define FILE_IN "fractii.in"
#define FILE_OUT "fractii.out"

#define MAX_PRIME 4000
int PRIME[MAX_PRIME];
int NR_PRIME;
int TOTIENT[1000001];

void init_prime()
{
	for (int i=0; i<MAX_PRIME; i++) PRIME[i] = 1;

	PRIME[0] = 0;
	PRIME[1] = 1;

	int citi = 2;
	NR_PRIME = 0;

	while (citi*citi <= MAX_PRIME)
	{
		if (PRIME[citi])
		{
			PRIME[NR_PRIME++] = citi;

			int x = citi*citi;

			while (x<MAX_PRIME)
			{
				PRIME[x] = 0;
				x += citi;
			}
		}
		
		citi++;
	}

	while (citi < MAX_PRIME)
	{
		if (PRIME[citi]) PRIME[NR_PRIME++] = citi;
		citi++;
	}
}

void init_totient()
{
	TOTIENT[1] = 1;
	for (int i=2; i<=1000000; i++)
	{
		int p;
		for (int j=0; j<MAX_PRIME; j++)
		{
			p = PRIME[j];

			if (p*p > i)
			{
				p = i;
				break;
			}
			if ((i % p) == 0) break;
		}

		int tot = p-1;
		int iCopy = i/p;
		while (!(iCopy % p))
		{
			tot *= p;
			iCopy /= p;
		}
		tot *= TOTIENT[iCopy];
		TOTIENT[i] = tot;
	}
}

int main()
{
	init_prime();
	init_totient();
	
    ifstream fisIn(FILE_IN);
    ofstream fisOut(FILE_OUT);

	int N;
    fisIn >> N;

    uint64_t total = 1;
    for (int i=2; i<=N; i++)
    {
		total += 2*TOTIENT[i];
	}

    fisOut << total;
}