Cod sursa(job #307202)

Utilizator cypryCiprian Oprisa cypry Data 23 aprilie 2009 17:44:36
Problema Fractii Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 1.48 kb
#include<stdio.h>
#include<stdlib.h>

int n;
long long nr;

char prim[1000003];
int prime[1000000],nr_prime;
int eph[1000003];

void eratostene(int n){
	int i,j,max;
	for(i=2;i<=n;++i)
		if(prim[i] == 0){
			max = n/i;
			for(j=2;j<=max;++j)
				prim[j*i]=1;
		}
	for(i=1;i<=n;++i)
		if(prim[i] == 0)
			prime[nr_prime++] = i;
	prime[nr_prime]=0x7FFFFFFF;
	eph[1]=1;
}

void read(void){
	FILE *f=fopen("fractii.in","r");
	fscanf(f,"%d",&n);
	fclose(f);
}

void scrie(void){
	FILE *f=fopen("fractii.out","w");
	fprintf(f,"%lld\n",nr);
	fclose(f);
}

int power(int b,int e){
	if(e==0) return 1;
	if(e==1) return b;
	int p = power(b,e >> 1);
	p *= p;
	if(e % 2 == 1)
		p *= b;
	return p;
}

int eulerPhi(int k){
	if(prim[k] == 0){
		eph[k] = k-1;
		return k-1;
	}
	int m=k,i=1,p=0;
	//gasim un divizor prim
	while((prime[i] <= k) && (k % prime[i] != 0))
		++i;
	//vedem la ce putere e divizorul
	while(m % prime[i] == 0){
		++p;
		m /= prime[i];
	}
	eph[k] = (prime[i]-1) * power(prime[i],p-1) * eph[m];
	return eph[k];
}

void numara(void){
	int i;
	nr=1;
	for(i=2;i<=n;++i)
		nr += 2*eulerPhi(i);
}

void test(){
	int i;
	for(i=2;i<=n;++i){
		printf("%d - %d\n",i,eulerPhi(i));
	}
}

int main(void){
	read();
	eratostene(n);
	//test();
	numara();
	scrie();
	return 0;
}

/*int cmmdc(int a,int b){
	if(a == 0)
		return b;
	if(b == 0)
		return a;
	if(a>b)
		a = a%b;
	else
		b = b%a;
	return cmmdc(a,b);
}

void numara1(void){
	int i,j;
	nr=1;
	for(i=1;i<=n;++i)
		for(j=1;j<i;++j)
			if(cmmdc(i,j) == 1)
				nr += 2;
}*/