Cod sursa(job #13998)

Utilizator airineivAirinei Vasile airineiv Data 7 februarie 2007 23:44:55
Problema Fractii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.6 kb
#include "stdio.h"


int main(void)
{
	unsigned int N, i, j, p, r, fi, mod, prod1, prod2;
	bool Eratostene[1000000];
	unsigned __int64 n;
	unsigned int divizor[1000];
	FILE *fin, *fout;
	if((fin = fopen("fractii.in", "r"))==NULL)
		return -1;
	if((fout = fopen("fractii.out", "w"))==NULL)
		return -1;
	fscanf(fin, "%d", &N);
	for(i=0; i<N; i++)
		Eratostene[i] = true;
	for(i=2; i*i<=N; i++)
	{
		if(Eratostene[i])
		{
			for(j=2; i*j<=N; j++)
				Eratostene[i*j] = false;
		}
	}
	i=0;
	n=N;
	for(i=2; i<=N; i++)
	{
		r=0;
		if(Eratostene[i])
			fi = i-1;
		else
		{
			p=i;	
			for(j=2; j<=N; j++)
			{
				if(Eratostene[j] && p%j == 0)
				{
					while(p%j==0)
						p = p/j;
					divizor[r++] = j;
					if(p==1)
						break;
				}
			}
			fi = i;
			prod1 = prod2 = 1;
			for(j=0; j<r; j++)
				prod1 *= (divizor[j]-1);
			for(j=0; j<r; j++)
				 prod2 *= divizor[j];
			fi = ((fi*prod1)/prod2);
		}
		mod = N%i;
		if(mod == 0)
			fi *= N/i;
		else
		{
			fi *= N/i;
			if(Eratostene[i])
				fi += mod;
			else
			{
				if(mod==1)
					fi++;
				else
				{
					while(mod>=1)
					{
						double t = ((double)mod*prod1)/(double)prod2;
						if(t - (int)t == 0)
						{
							fi += (int)(t);
							break;
						}
						bool relativPrime = true;
						for(j=0; j<r; j++)
						{
							if(mod % divizor[j]==0)
							{
								relativPrime = false;
								break;
							}
						}
						if(relativPrime)
							fi++;
						mod--;
					}
					
				}
			}
		}
		n+=fi;
	}
	fprintf(fout, "%d", n);
	fclose(fin);
	fclose(fout);
	return 0;
}