Cod sursa(job #1631980)

Utilizator on_a_mission_without_permissionUPB Bolohan Dinu Rotaru on_a_mission_without_permission Data 5 martie 2016 20:38:19
Problema Fractii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.06 kb
// problema incearca sa afle numarul de fractii distincte a/b cu a,b < n
// foloseste Sieve of Erathosthene

#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
//long long prime[100000];
int nr_prime;
vector<long> prime;
void calculeazaprime(){
	long long i,j;
	int gasit;
	nr_prime = 0;
	for( i = 2; i <= 1000000; i++){
		gasit = 0;
		for( j = 0; j < nr_prime; j++)
			if( i % prime[j] == 0){
				gasit = 1;
				break;
			}
		if( gasit == 0)
			prime[nr_prime++] = i;
	}
}
long sieve[1000000];
void calculeazaprime2(){
//	char b[1000000];
	long i, j;
	for( i = 0; i < 1000000; i++)
		sieve[i] = 1;
	for( i = 2; i < 1000000; i++){
		if( sieve[i] == 1 ){
			prime.push_back(i);
			for(j = 2; j <= 1000000 / i; j++)
				sieve[i * j] = i;
		}
	}
}
long cautare_binara(long nr){
	long fin;
	if(nr >= fin)
		return fin;
	return upper_bound(prime.begin(), prime.end(), nr) - prime.begin();
}

long long nr_rel_prim(long nr){
//	printf("mi-a intrat in functie cu nr = %ld \n", nr);
//	return 0;
	if( nr <= 1)
		return 1;
	if( sieve[nr] == 1)
		return nr - 1;
	long long ret, prim;
	prim = sieve[nr];
	ret = prim - 1;
	nr /= prim;
	while(nr && nr % prim == 0){
		nr /= prim;
		ret *= prim;
	}
	return ret * nr_rel_prim(nr);
}
/*
	
	
	
	long i, prim;













	i = cautare_binara(nr);
	while( nr > 1 && i >= 0){
//		printf("compar %ld cu %ld\n", nr, prime[i]);
		prim = prime[i];
		if( nr % prim == 0){
			nr /= prim;
			ret *= (prim - 1);
			while( nr && (nr % prim == 0) ){
				nr /= prim;
				ret *= prim;
			}
		}
		i--;
	}
//	if( nr > 2)
//		ret *= (nr - 1);
//	printf("pt nr = %lld returnez %lld\n",nr, ret);
	return ret;
}
*/
int main(){
	long n;
	long long rez;
	rez = 0;
	FILE *f = fopen("fractii.in", "r");
	fscanf(f, "%ld", &n);
	fclose(f);
//	printf("n = %ld\n", n);
	long i;
	calculeazaprime2();
//	printf("aici n = %ld\n", n);
//	return 0;
//	printf("mi-a iesit din functio\n");
	rez++;
	for( i = 2; i <= n; i++){
//		printf("aici i = %ld, n = %ld\n",i,n);
		rez += 2 * nr_rel_prim(i);
	}
	f = fopen("fractii.out", "w");
	fprintf(f, "%lld", rez);
	fclose(f);
	return 0;
}