https://www.spoj.com/problems/LCMSUM/
[egin{aligned}
ans&=sum_{i=1}^nlcm(i,n) \
&=sum_{i=1}^n frac{i*n}{gcd(i,n)} \
&=sum_{d=1}^nsum_{i=1}^n[gcd(i,n)=d]frac{i*n}{gcd(i,n)} \
&=sum_{d=1}^nsum_{i=1}^{lfloorfrac{n}{d}
floor}[gcd(i,frac{n}{d})=1] i*n \
&=n*sum_{d=1}^nsum_{i=1}^{lfloorfrac{n}{d}
floor}[gcd(i,frac{n}{d})=1] i \
&=n*sum_{d=1}^nsum_{i=1}^d[gcd(i,d)=1] i \
end{aligned}
]
令
[f(i)=sum_{i=1}^d[gcd(i,d)=1]i
]
则
[ans=n*sum_{d=1}^nf(d)
]
如果我们求出了所有的(f(d)),那么枚举d,让d,2d,3d……kd 都加上这个(f(d)),最后各自再乘上自己,就算完了。这个复杂度是(nlog_2n)
(f(i))怎么算?
我们发现(f(i))就是所有与小于等于(i)且与(i)互质的数的和
(f(1)=1)
当(i>1)时,(f(i)=phi(i)*i/2),因为(gcd(j,i)=gcd(i-j,i)),即与(i)互质的数成对出现,且每一对相加等于(i)
#include<bits/stdc++.h>
using namespace std;
#define N 1000001
int phi[N],prime[N],cnt;
bool check[N];
long long ans[N];
void euler()
{
phi[1]=1;
for(int i=2;i<=N;i++)
{
if(!check[i])
{
prime[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt;j++)
{
if(i*prime[j]>=N) break;
check[i*prime[j]]=true;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
void pre()
{
for(int i=2;i<N;++i)
for(int j=i;j<N;j+=i)
ans[j]+=1ll*i*phi[i]/2;
for(int i=1;i<N;++i) ans[i]++;
for(int i=1;i<N;++i) ans[i]*=i;
}
int main()
{
euler();
pre();
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
printf("%lld
",ans[n]);
}
}