Cod sursa(job #935842)

Utilizator dariusdariusMarian Darius dariusdarius Data 4 aprilie 2013 22:10:54
Problema Mins Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.49 kb
#include<stdio.h>
#include<algorithm>
using namespace std;
int p[10];
int phi[1000005];
int  dp[1000005];
inline int sqr(int x)
{
    int ans=0;
    for(int pas=1<<13;pas;pas>>=1)
        if((ans+pas)*(ans+pas)<=x)
            ans+=pas;
    return ans;
}
long long pinex(int x,int y)
{
    ///numarul de numere <=x si prime cu y:
    int ans=x,q,nr,f=0;
//descompunem in factori:
    while(y>1)
    {
        if(f==0 || p[f-1]!=dp[y])
            p[f++]=dp[y];
        y=y/dp[y];
    }
//generam submultimi cu factorii primi:
    for(int i=1;i<(1<<f);i++)
    {
        nr=0;q=1;
        for(int j=0;j<f;j++)
            if(i&(1<<j))
                nr++,q*=p[j];
        if(nr&1) ans-=x/q;
        else ans+=x/q;
    }
    return ans;
}
int main()
{
    freopen("mins.in","r",stdin);
    freopen("mins.out","w",stdout);
    int n,m;long long ans=0;
    scanf("%d%d",&m,&n);m--;n--;
    if(m>n) swap(n,m);
//mai intai vedem patratul care se poate rezolva ∑phi(i)
    for(int i=1;i<=m;i+=2) phi[i]=i;
    for(int i=2;i<=m;i+=2) phi[i]=i/2;
    for(int i=3;i<=m;i+=2)
	if(phi[i]==i)
	    for(int j=i;j<=m;j+=i)
		phi[j]=phi[j]/i*(i-1);
    for(int i=1;i<=m;i++)
	ans=ans+phi[i];
    ans=2*ans-1;
//pregenerari pentru descompunere in factori:
    for(int i=3;i<=n;i+=2) dp[i]=i;
    for(int i=2;i<=n;i+=2) dp[i]=2;
    for(int i=3;i<=n;i+=2)
        if(dp[i]==i)
            for(int j=3*i;j<=n;j=j+2*i)
                dp[j]=i;

    for(int i=m+1;i<=n;i++)
        ans+=pinex(m,i);

    printf("%lld\n",ans);
    return 0;
}