Cod sursa(job #65352)

Utilizator sealTudose Vlad seal Data 8 iunie 2007 20:47:27
Problema Sum Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.1 kb
#include<stdio.h>
#include<stdlib.h>
#define Xm 100001
int P[Xm],Pk[Xm],Phi[Xm];
long long Sum[Xm];

void preprocess()
{
    int i,j;


    for(i=4;i<Xm;i+=2)
	P[i]=2;
    for(i=3;i*i<Xm;i+=2)
	if(!P[i])
	    for(j=i*i;j<Xm;j+=2*i)
		P[j]=i;
    for(i=3;i<Xm;i++)
	if(!P[i])
	    P[i]=Pk[i]=i;
	else
	{
	    Pk[i]=P[i];
	    while(i%(Pk[i]*P[i])==0)
		Pk[i]*=P[i];
	}


    Phi[2]=Sum[2]=1;
    for(i=3;i<Xm;++i)
    {
	j=i/Pk[i];
	if(j>1)
	{
	    Phi[i]=Phi[j]*Phi[Pk[i]];
	    Sum[i]=Sum[j]*Pk[i]+(((long long)Pk[i]*(Pk[i]-1)*Phi[j]*j)>>1);
	    Pk[i]/=P[i];
	    Sum[i]-=(Sum[j]*Pk[i]+(((long long)Pk[i]*(Pk[i]-1)*Phi[j]*j)>>1))*P[i];
	}
	else
	{
	    Phi[i]=Pk[i]-Pk[i]/P[i];
	    Sum[i]=(long long)Pk[i]*Phi[i]>>1;
	}
    }
    for(i=2;i<Xm;++i)
	Sum[i]+=Sum[i]+(long long)Phi[i]*i;
}

void solve()
{
    char S[7];
    int n;

    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    scanf("%d\n",&n);
    while(n--)
    {
	gets(S);
	printf("%lld\n",Sum[atoi(S)]);
    }
}

int main()
{
    preprocess();
    solve();
    return 0;
}