Description
求解(多组数据)
1⩽T⩽3×105 1 ⩽ T ⩽ 3 × 10 5 , 1⩽n⩽106 1 ⩽ n ⩽ 10 6
Solution
易得原式即
根据
gcd(a,n)=1
gcd
(
a
,
n
)
=
1
时一定有
gcd(n−a,n)=1
gcd
(
n
−
a
,
n
)
=
1
,可将原式化为
上述式子中括号内的两个
∑
∑
对应的项相等,故又可以化为
可以将相同的 gcd(i,n) gcd ( i , n ) 合并在一起计算,故只需要统计 gcd(i,n)=d gcd ( i , n ) = d 的个数。当 gcd(i,n)=d gcd ( i , n ) = d 时, gcd(id,nd)=1 gcd ( i d , n d ) = 1 ,所以 gcd(i,n)=d gcd ( i , n ) = d 的个数有 φ(nd) φ ( n d ) 个。
故答案为
变换求和顺序,设
d′=nd
d
′
=
n
d
,式子化为
设 g(n)=∑d|nd⋅φ(d) g ( n ) = ∑ d | n d ⋅ φ ( d ) ,已知 g g 为积性函数,于是可以 Θ(n) Θ ( n ) 预处理。最后枚举 d d ,统计贡献即可。
时间复杂度:
Code
#include <cstdio>
const int N=1000000;
int tot,p[N+5],phi[N+5];
long long ans[N+5];
bool flg[N+5];
void solve() {
phi[1]=1;
for(int i=2;i<=N;++i) {
if(!flg[i]) p[++tot]=i,phi[i]=i-1;
for(int j=1;j<=tot&&i*p[j]<=N;++j) {
flg[i*p[j]]=1;
if(i%p[j]==0) {
phi[i*p[j]]=phi[i]*p[j];
break;
}
phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
for(int i=1;i<=N;++i) {
for(int j=1;i*j<=N;++j) {
ans[i*j]+=1LL*j*phi[j]/2;
}
}
for(int i=1;i<=N;++i) ans[i]=1LL*i*ans[i]+i;
}
int main() {
int T,n;
solve();
for(scanf("%d",&T);T;--T) {
scanf("%d",&n);
printf("%lld\n",ans[n]);
}
return 0;
}