Cod sursa(job #651673)

Utilizator eduEduard Gabriel Bazavan edu Data 21 decembrie 2011 01:02:02
Problema Fractii Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.14 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <bitset>
using namespace std;

#define MAXN 1000000
#define MAXP 1024

bitset<MAXN> visited;

int nP;
int32_t P[MAXP];
int32_t phi[MAXN];

void find_primes(int N) {
	
	visited.set();
	nP=0;
	for (int i=2; i <= N;) {
		P[nP++]=i;
		int j=2*i;
		while (j <= N) {
			visited[j] = 0;
			j+=i;
		}
		while (visited[++i] == 0);
	}
}

int find_power(int x, int p) {
	int c=1;
	while (x%p == 0) {
		c*=p;
		x/=p;
	}
	return c;
}

int main() {

	freopen("fractii.in", "rt", stdin);
	freopen("fractii.out", "wt", stdout);

	int N;
	scanf("%d\n", &N);

	find_primes(N);
	
	memset(phi, 0, N * sizeof(int32_t));
	phi[1]=1;
		
	int64_t sum=phi[1];
	for (int i=2; i <= N; i++) {
		for (int j=0; P[j] <= i && j < nP; j++) {
			if (i % P[j] == 0) {
				int q = find_power(i, P[j]);
				phi[i] = (q/P[j] * (P[j]-1)) * phi[i/q];
			}
		}
		sum += (int64_t ) 2*phi[i];
	}

	/*	
	printf("nP %d\n", nP);
	for (int i=0; i < nP; i++) {
		printf("%d ", P[i]);
	}
	printf("\n");
	for (int i=1; i <= N; i++) {
		printf("%d ", phi[i]);
	}
	printf("\n");
	*/
	printf("%lld\n", sum);

	fclose(stdin);
	fclose(stdout);

	return 0;
}