Cod sursa(job #397821)

Utilizator AndreyPAndrei Poenaru AndreyP Data 17 februarie 2010 15:47:13
Problema Mins Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.55 kb
#include<stdio.h>
#define N 1000001
#define P 78510
#define ll long long
int c,d;
unsigned int a[15630];
ll b[N];
int p[P];
int p1[30];
ll rez;
ll d1;
//int CATE;
inline void swap(int &x,int &y)
{
	int aux=x;
	x=y;
	y=aux;
}
inline void ciur()
{
	p[0]=1;
	p[1]=2;
	int i;
	for(i=3; i*i<N; i+=2)
	{
		if((a[i>>6]&(1<<((i>>1)&31)))!=0)
			continue;
		p[++p[0]]=i;
		for(int j=i*i,i1=i<<1; j<N; j+=i1)
			a[j>>6]|=1<<((j>>1)&31);
	}
	for(; i<N; i+=2)
	{
		if((a[i>>6]&(1<<((i>>1)&31)))!=0)
			continue;
		p[++p[0]]=i;
	}
}
inline void vezi(int k)
{
	int k1=k;
	p1[0]=0;
	if((k&1)==0)
	{
		k>>=1;
		if((k&1)==0)
		{
			rez+=b[k];
			b[k1]=b[k];
			return;
		}
		++p1[0];
		p1[1]=2;
	}
	for(int i=2; p[i]*p[i]<=k; ++i)
	{
		if(k%p[i]==0)
		{
			p1[++p1[0]]=p[i];
                        k/=p[i];
			if(k%p[i]==0)
			{
				b[k1]=b[k1/p[i]];
				rez+=b[k1];
				return;
			}
		}
	}
	if(k!=1)
		p1[++p1[0]]=k;
	//++CATE;
        ll r=d1;
	int lim=1<<p1[0];
	int x,nrb;
	for(int i=1; i<lim; ++i)
	{
                nrb=0;
		x=1;
                for(int j=1,care=1; j<=i; j<<=1,++care)
		{
			if((i&j)==0)
				continue;
                        x*=p1[care];
			++nrb;
		}
                if((nrb&1)==1)
			r-=(ll)(d/x);
		else
			r+=(ll)(d/x);
	}
	b[k1]=r;
	rez+=r;
}
int main()
{
	freopen("mins.in","r",stdin);
	freopen("mins.out","w",stdout);

	scanf("%d%d",&c,&d);
        if(c>d)
		swap(c,d);
	ciur();
	--d;
	d1=(ll)d;
        for(int i=2; i<c; ++i)
	{
		vezi(i);
		//fprintf(stderr,"%d --> %lld\n",i,b[i]);
	}
	rez+=(ll)d;

	printf("%lld\n",rez);
	//fprintf(stderr,"%d\n",CATE);
	return 0;
}