Description
求
∑i=1n∑j=1nφ(gcd(φ(i),φ(j)))∑i=1n∑j=1nφ(gcd(φ(i),φ(j)))
n<=2*10^6
Solution
感觉还是数学题写得舒心( ̄▽ ̄)”
令s(d)=∑ni=1[φ(i)=d]s(d)=∑i=1n[φ(i)=d]
套路地枚举gcd得到
∑d=1nφ(d)∑i=1⌊nd⌋s(di)∑j=1⌊nd⌋s(dj)[gcd(i,j)=1]∑d=1nφ(d)∑i=1⌊nd⌋s(di)∑j=1⌊nd⌋s(dj)[gcd(i,j)=1]
然后直接拉出来有
∑d=1nφ(d)∑x=1⌊nd⌋μ(x)⎛⎝∑i=1⌊ndx⌋s(dxi)⎞⎠2∑d=1nφ(d)∑x=1⌊nd⌋μ(x)(∑i=1⌊ndx⌋s(dxi))2
令f(x)=∑⌊nx⌋i=1s(xi)f(x)=∑i=1⌊nx⌋s(xi)
这个f是可以nlogn求的,这整个柿子也是可以nlogn求的,直接在线做就可以了
注意到题目并没有给模数,因此这题是不用膜的(废话
Tnlogn的复杂度不太像能过,要卡卡才能过
Code
#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (register int i=st;i<=ed;++i)
typedef long long LL;
const int N=2000005;
LL f[N+5],phi[N+5];
int mu[N+5],prime[N+5],s[N+5];
bool not_prime[N+5];
void pre_work(int n) {
phi[1]=mu[1]=1;
rep(i,2,n) {
if (!not_prime[i]) {
prime[++prime[0]]=i;
phi[i]=i-1; mu[i]=-1;
}
for (int j=1;i*prime[j]<=n&&j<=prime[0];++j) {
int x=i*prime[j];
not_prime[x]=true;
if (i%prime[j]==0) {
mu[x]=0; phi[x]=phi[i]*prime[j];
break;
}
mu[x]=-mu[i]; phi[x]=phi[i]*(prime[j]-1);
}
}
}
void solve(int n) {
rep(i,1,n) {
s[i]=0;
s[phi[i]]++;
}
rep(i,1,n) {
f[i]=0;
for (int j=i;j<=n;j+=i) {
f[i]+=s[j];
}
f[i]*=f[i];
}
LL ans=0;
rep(i,1,n) {
LL tmp=0;
for (int j=1;i*j<=n;++j) {
tmp+=f[i*j]*mu[j];
}
ans=ans+tmp*phi[i];
}
printf("%lld\n", ans);
}
int main(void) {
pre_work(N);
int T; for (scanf("%d",&T);T--;) {
int n; scanf("%d",&n);
solve(n);
}
return 0;
}