Description
求ANS=∑i=1n∑j=1nφ(gcd(φ(i),φ(j)))
n<=2*10^6
Solution
一道极裸的反演题。
设p(k)=∑[φ(i)=k]
f(d)=∑∑[gcd(φ(i),φ(j))=d]=∑∑[gcd(i,j)=d]p(i)p(j)
都是套路
g(d)=∑i=1ndf(id)
ANS=∑d=1nφ(d)f(d)=∑d=1nφ(d)∑i=1ndμ(i)g(id)
g怎么求?
如果没有
但是有p怎么办?
不虚
再设
ANS=∑d=1nφ(d)∑i=1ndμ(i)S(id)2
因为∑i=1nni≈nlog(n)
所以直接暴力做就是O(nlogn)的,注意卡常。
Code
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
#define N 2000005
using namespace std;
int mu[N],pr[N],n,t,l,phi[N];
LL s[N],p[N];
bool bz[N];
void prp(int n)
{
l=0;
mu[1]=phi[1]=p[1]=1;
fo(i,2,n)
{
if(bz[i]==0) pr[++l]=i,mu[i]=-1,phi[i]=i-1;
p[phi[i]]++;
for(int j=1;j<=l&&i*pr[j]<=n;j++)
{
bz[i*pr[j]]=1;
if(i%pr[j]==0)
{
mu[i*pr[j]]=0;
phi[i*pr[j]]=phi[i]*pr[j];
break;
}
phi[i*pr[j]]=phi[i]*(pr[j]-1);
mu[i*pr[j]]=-mu[i];
}
bz[i]=0;
}
fo(d,1,n)
{
s[d]=0;
fo(i,1,n/d) s[d]+=p[i*d];
}
}
int main()
{
cin>>t;
while(t-->0)
{
scanf("%d",&n);
LL ans=0;
prp(n);
fo(d,1,n)
{
LL s1=0;
p[d]=0;
fo(i,1,n/d) s1+=mu[i]*s[i*d]*s[i*d];
ans+=s1*phi[d];
}
printf("%lld\n",ans);
}
}