Cod sursa(job #135726)

Utilizator bilygates2005Liviu Cristian Mirea-Ghiban bilygates2005 Data 14 februarie 2008 11:59:46
Problema Fractii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.66 kb
#include<stdio.h>
#include<math.h>

long long sum=0;
long v[1000001L][11], n, pows[20];
int vc[1000001L];
char vnotprime[1000001L],vsquare[1000001L];

int doit()
{
	long i,j,k,l,s;
    long long p,d;
	
	//genereaza puterile lui 2
	pows[0]=1;
    i=0;
	while(pows[i]<n)
	{
        i++;
        pows[i]=pows[i-1]*2;
    }
	
	//genereaza numerele prime
	for(i=2;i<=n;i++)
	{
		s=long(sqrt(i));
		if(s*s==i)//daca este patrat perfect
		{
			vsquare[i]=1;
		}
		s=i+i;
		while(s<=n)//ex.: i=2; luam 4, 6, 8, 10...
		{
			if(vnotprime[i]==0)//daca nu are niciun divizor patrat perfect
			{
				v[s][vc[s]]=i;
				vc[s]++;
			}
			vsquare[s]=vsquare[i];
			vnotprime[s]=1; //numarul nu e prim
			s+=i;
		}
	}
	sum=1;
	for(i=2;i<=n;i++)
	{
        sum+=n;
        for(j=0;j<vc[i];j++)
        {
            sum-=(n/v[i][j]);
        }
        if(vc[i]>2)
        {
            p=pow(2,vc[i])-1;
            for(k=1;k<p;k++)
            {
                d=1;
                for(l=0;l<vc[i];l++)
                {
                    if(k & pows[l])
                    {
                        d*=v[i][l];
                    }
                }
                //printf("%ld ",d);
                sum-=(n/d);
            }
        }
//        printf("%lld\n",sum);
    }
    
	return 0;		
}

int main()
{
	freopen("fractii.in","r",stdin);
	freopen("fractii.out","w",stdout);
	
	scanf("%ld",&n);	
	doit();
	printf("%Ld",sum);
/*	
	long i,j;
	for(i=2;i<=n;i++)
	{
		printf("\n%ld -> ",i);	
		for(j=0;j<vc[i];j++)
		{
			printf("%ld, ",v[i][j]);
		}	
	}
	*/
	fclose(stdin);
	fclose(stdout);
	return 0;
}