Cod sursa(job #66519)

Utilizator nuexistnuexist nuexist Data 19 iunie 2007 16:10:27
Problema Fractii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <cstdio>
#define maxn 1<<20

bool t[maxn];
int primes[maxn], T;
int n;
int totent[maxn];
void citire()
{
	freopen("fractii.in", "r", stdin);
	scanf("%d", &n);
}

void prim()
{
	int i, j;
	for(i=4;i<=n;i+=2) t[i]=1;
	
	for(i=3;i<=n;i+=2)
		if(!t[i])
		{
			for(j=i+i;j<=n;j+=i) t[j]=1;
		}
	for(i=2;i<=n;i++) if(!t[i]) primes[++T]=i;
			
}

int tot(int k)
{
	
	int i, p=k/2;
	 double sum=k;
	if(t[k]==0) return k-1;
	for(i=1;i<=T;i++)
	{
		if(primes[i]>p) break;
		if(k%primes[i]==0)
		{
			sum=sum*((primes[i]-1.0)/(double)primes[i]);
		}
	}
	if(sum==k) return (int) sum-1;
	return (int) sum;
}
			

int main()
{
	citire();
	prim();
	//printf("%d\n", tot(7));
	
	

	
	totent[2]=1;
	totent[3]=2;
	
	for(int i=1;i<=T && primes[i]*primes[i]<=n;i++)
	{
		int r=primes[i];
		totent[r]=r-1;
		int tt=r*r;
		int nr=2;
		
		while(tt<=n)
		{
			if(totent[tt]==0) totent[tt]=(r-1)*(tt/r);
			//printf("(%d %d %d)\n", tt, r-1, nr);
			nr++;
			tt=tt*r;
		}
	}

	
	
	for(int i=4;i<=n;i++)
	if(totent[i]==0)
	{
		if(t[i]==0) totent[i]=i-1;
		else
		{
			int prim, P=i, nr=0, j;
			for(j=1;j<=T;j++)
				if(i%primes[j]==0) { prim=primes[j]; break;}
		
			while(1)
			{
				if(P%prim) break;
				P=P/prim;
				nr++;
			}
			//printf("%d ___%d\n", prim, nr);
			int tt=1;
			for(j=1;j<=nr;j++)tt*=prim;
		
			if(tt==i)
			{
				totent[i]=(prim-1)*(tt/prim);
				//printf("(%d %d)\n", prim, nr);
			}
			else
			{
			int qq=i/tt;
			//printf("%d   %d ____%d          %d\n",i, tt, qq,nr);
			totent[i]=totent[tt]*totent[qq];
		
			}
		}
	}

	
	//for(int i=2;i<=n;i++) printf("%d %d\n", tot(i), totent[i]);
	long long sum=0;
				
				
	for(int i=2;i<=n;i++) sum+=(long long)totent[i];
	

	sum*=2;
	sum++;
	
	freopen("fractii.out", "w", stdout);
	printf("%lld\n", sum);
	
	
return 0;
}