Cod sursa(job #172636)

Utilizator mihai.ioluMihai Iolu mihai.iolu Data 6 aprilie 2008 16:53:08
Problema Fractii Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.44 kb
#include<fstream>
//#include<iostream>
#include<math.h>

using namespace std;

long a[20];
int ciur[1000001];
int prime[1000001];
long pr=0;

void gen_ciur(long n)
{
	memset(ciur, 0, sizeof(ciur));
	ciur[1]=1;
	for(long i=4;i<=n;i=i+2)
		ciur[i]=1;
	for(long i=3;i<=n;i=i+2)
	{
		int k=i;
		while((k=k+i)<=n)
			ciur[k]=1;
	}
	prime[1]=2; 
	pr=1;
	for(int i=3;i<=n;i=i+2)
		if(ciur[i]==0)
			prime[++pr]=i;
	//cout<<pr<<" numere prime"<<endl;
}

long nrelem(long n, long a[20], int m)
{
	long s=0;

	for(long i=1;i<(1<<m);i++)
	{
		long p=1,nr=0, t=i, c;
		for(int j=1;j<=m;j++)
		{
			 c=1 & t;
			 t=t>>1;
			 if(c)
				 p=p*a[j];
			 nr+=c;
		}
		if(nr%2==1)
			s+=n/p;
		else
			s-=n/p;
	}
	return n-s;
}

long fracnum(long x, long n)
{
	int m=0;
	if(ciur[x]==1)
	{
		/*long num=(long)sqrt((double)x);
		if((x==num*num) && (ciur[num]==0))
		{
			a[m=1]=num;
			x=1;
		}
		if(x%2==0)
		{
			a[m=1]=2;
			while(x%2==0)
				x/=2;
		}*/
		long d=1;
		while(x>1)
		{
			if(x%prime[d]==0)
			{
				a[++m]=prime[d];
				while(x%prime[d]==0)
					x/=prime[d];
			}
			d++;
		}
	}
	else
		a[m=1]=x;
	return nrelem(n,a,m);
}

int main()
{
	ifstream f("fractii.in");
	ofstream g("fractii.out");
	long n;
	f>>n;
	gen_ciur(n);
	long long s=1L;
	for(int i=n;i>=2;i--)
	{
		s+=fracnum(i,i);
		//if(i%10000==0)
			//cout<<i<<endl;
	}
	g<<2*s-1;
	f.close();
	g.close();
	return 0;
}