题解 SP5971 【LCMSUM - LCM Sum】
欧拉函数。算是对 @BJpers2 巨佬的代码补充。
本文同步发表于笔者的博客:题解 SP5971 LCMSUM - LCM Sum
推公式过程如下:
转化
后面这个等于
可以预处理时把每个
#include<bits/stdc++.h>
#define MAXN 1000000
#define ll long long
using namespace std;
int pri[MAXN+5],tot,phi[MAXN+5];
ll f[MAXN+5];
bool isp[MAXN+5];
void GetPrime()
{
phi[1]=1;
isp[1]=1;
for(int i=2;i<=MAXN;i++)
{
if(!isp[i])
{
pri[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot && i*pri[j]<=MAXN;j++)
{
isp[i*pri[j]]=1;
if(i%pri[j]) phi[i*pri[j]]=phi[i]*phi[pri[j]];
else
{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
}
}
for(int i=1;i<=MAXN;i++)
{
for(int j=1;i*j<=MAXN;j++) f[i*j]+=(i==1?1:1ll*phi[i]*i/2);
}
}
int main()
{
GetPrime();
int Time;
scanf("%d",&Time);
while(Time--)
{
int n;
scanf("%d",&n);
printf("%lld\n",f[n]*1ll*n);
}
return 0;
}