题面
题目要我们求
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn=1000000;
int n,pri[maxn+5],num,mu[maxn+5],d[maxn+5],sm[maxn+5],sd[maxn+5];
bool flag[maxn+5];
void getpri(int n)
{
memset(flag,1,sizeof(flag));
flag[1]=0;mu[1]=1;
for(int i=2;i<=n;i++)
{
if(flag[i]) pri[++num]=i,mu[i]=-1;
for(int j=1;j<=num&&i*pri[j]<=n;j++)
{
flag[i*pri[j]]=0;
if(i%pri[j]==0) {mu[i*pri[j]]=0;break;}
mu[i*pri[j]]=-mu[i];
}
}
}
ll qsd(int m)
{
if(m<=maxn) return sd[m];
ll re=0;
for(int l=1,r=1,k;l<=m;l=r+1)
{
k=m/l;r=m/k;
re+=(ll)(r-l+1)*k;
}
return re;
}
ll qsm(int m)
{
if(m<=maxn) return sm[m];
int gen=round(sqrt(m)+1);ll re=0;
for(int i=1;i<=gen;i++)
re+=mu[i]*(m/(i*i));
return re;
}
ll solve()
{
ll re=0;
for(int l=1,r=1,k;l<=n;l=r+1)
{
k=n/l;r=n/k;
re+=qsd(k)*(qsm(r)-qsm(l-1));
}
return re;
}
int main()
{
int ca;
scanf("%d",&ca);
getpri(maxn);
for(int i=1;i<=maxn;i++)
for(int j=1;i*j<=maxn;j++)
d[i*j]++;
for(int i=1;i<=maxn;i++)
sm[i]=sm[i-1]+mu[i]*mu[i],sd[i]=sd[i-1]+d[i];
while(ca--)
{
scanf("%d",&n);
printf("%lld\n",solve());
}
return 0;
}