Cod sursa(job #118698)

Utilizator rapidu36Victor Manz rapidu36 Data 27 decembrie 2007 16:54:10
Problema Fractii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.34 kb
#include<stdio.h>
#define N 1000010
char c[N];
int e[N],p[1000],nr=0;
//e[i]=ind lui euler pt i; p[i]=al i-lea nr prim (pana in rad de n)-> imi optimizeaza functia divizor

void ciur(int n){
	int i,j;
	c[0]=c[1]=1;
	for(j=4;j<=n;j+=2)
		c[j]=1;
	for(j=6;j<=n;j+=3)
		c[j]=1;
	p[nr++]=2;
	p[nr++]=3;
	for(i=5;i*i<=n;i+=4){
		if(!c[i]){
			for(j=5*i;j<=n;j+=6*i)
				c[j]=1;
			for(j=7*i;j<=n;j+=6*i)
				c[j]=1;
			p[nr++]=i;
		}
		i+=2;
		if(!c[i]){
			for(j=5*i;j<=n;j+=6*i)
				c[j]=1;
			for(j=7*i;j<=n;j+=6*i)
				c[j]=1;
			p[nr++]=i;
		}
	}
}
/*
void ciur(int n){
	int i,j;
	c[0]=c[1]=1;
	for(i=2;i*i<=n;++i)
		if(!c[i]){
			p[nr++]=i;
			for(j=i+i;j<=n;j+=i)
				c[j]=1;
		}
}
*/
/*
void scrie(int n){
	for(int i=2;i<=n;++i)
		if(!c[i])
			printf("%d ",i);
	printf("\n");
}
*/
int divizor(int x){
	for(int i=0;i<nr;++i)
		if(x%p[i]==0)
			return p[i];
	return 1;
}
long long euler(int n){
	int i,d;
	long long s=0;
	for(i=2;i<=n;++i){
		if(!c[i])
			e[i]=i-1;
		else{
			d=divizor(i);
			if(i%(d*d))
				e[i]=(d-1)*e[i/d];
			else
				e[i]=d*e[i/d];
		}
		s+=e[i];
	}
	return (s<<1)+1;
}
int main(){
	int n;
	freopen("fractii.in","r",stdin);
	freopen("fractii.out","w",stdout);
	scanf("%d",&n);
	ciur(n);
	printf("%lld\n",euler(n));
	fclose(stdin);
	fclose(stdout);
	return 0;
}