Description
Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Least Common Multiple of the integers i and n.
做法一:
有这个结论就很简单了:小于等于n且与n互质的数的和,然后就可以 O(nlogn) 预处理出所有的答案。( n+n2+n3....+1 )是 O(nlogn) 的。
做法二:
莫比乌斯反演。
大力推式子:
#include
using namespace std;
#define LL long long
#define pa pair
const int Maxn=1000010;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
int prime[Maxn>>1],len=0;
LL phi[Maxn],ans[Maxn],sum[Maxn];
bool mark[Maxn];
void pre()
{
memset(mark,false,sizeof(mark));
phi[1]=1;
for(int i=2;i<=1000000;i++)
{
if(!mark[i]){prime[++len]=i;phi[i]=i-1;}
for(int j=1;j<=len&&prime[j]*i<=1000000;j++)
{
mark[prime[j]*i]=true;
if(i%prime[j]==0)
{
phi[prime[j]*i]=prime[j]*phi[i];
break;
}
phi[prime[j]*i]=(prime[j]-1)*phi[i];
}
}
sum[1]=1;
for(int i=2;i<=1000000;i++)sum[i]=phi[i]*(LL)(i)/2LL;
for(int i=1;i<=1000000;i++)
for(int j=i;j<=1000000;j+=i)
ans[j]+=sum[i];
for(int i=1;i<=1000000;i++)ans[i]*=(LL)(i);
}
int main()
{
pre();
int T=read();
while(T--)printf("%lld\n",ans[read()]);
}
#include
using namespace std;
#define LL long long
#define pa pair
const int Maxn=1e6+10;
const int inf=1e6;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
int prime[Maxn],len=0,mu[Maxn];
bool mark[Maxn];
LL F[Maxn],ans[Maxn];
LL Sum(LL l,LL r,LL c)
{
LL x=(r-l)/c+1;
return (l+r)*x/2LL;
}
void pre()
{
memset(F,0,sizeof(F));
memset(ans,0,sizeof(ans));
memset(mark,false,sizeof(mark));
mu[1]=1;
for(int i=2;i<=inf;i++)
{
if(!mark[i])prime[++len]=i,mu[i]=-1;
for(int j=1;j<=len&&prime[j]*i<=inf;j++)
{
mark[prime[j]*i]=true;
if(i%prime[j]==0){mu[prime[j]*i]=0;break;}
mu[prime[j]*i]=-mu[i];
}
}
for(int d=1;d<=inf;d++)
for(int x=d;x<=inf;x+=d)
F[x]+=(LL)(mu[d]*Sum(d,(x/d)*d,d));
for(int d=1;d<=inf;d++)
for(int x=d;x<=inf;x+=d)
ans[x]+=F[x/d]*(LL)(x);
}
int main()
{
pre();
int T=read();
while(T--)printf("%lld\n",ans[read()]);
}