一个不被讨厌的数质因数分解后一定是若干个指数为1的质数的积,然后二分答案,网上都说上界是2*k(why?),然后只要判断mid之内有多少不被讨厌的数就行了。。这个数会=mid-所有单个质数的平方+所有两个质数的平方-所有3个质数的平方……发现前面的系数(-1)^k不就是莫比乌斯函数吗。。对于一个数i,mu(i)*[mid/i^2]就是它对答案的贡献,那只要先线性筛一下莫比乌斯函数,然后从1枚举到√mid累加就行了。。
#include<iostream>
#include<cstdio>
#include<memory.h>
#include<cmath>
#define N 100005
#define ll long long
using namespace std;
ll k,l,r,mid;
int T,cnt,p[N],mu[N],u[N];
void getmu(int n)
{
mu[1]=1;cnt=0;
memset(u,0,sizeof(u));
for (int i=2;i<=n;i++)
{
if (!u[i]) p[++cnt]=i,mu[i]=-1;
for (int j=1;j<=cnt&&i*p[j]<=n;j++)
{
u[i*p[j]]=1;
if (i%p[j]==0)
{
mu[i*p[j]]=0;break;
}
else mu[i*p[j]]=-mu[i];
}
}
}
ll cal(ll x)
{
ll ans=0ll;
for (int i=1;i<=sqrt(x);i++) ans+=mu[i]*(x/(ll)(i*i));
return ans;
}
int main()
{
getmu(100000);
scanf("%d",&T);
while (T--)
{
scanf("%I64d",&k);
l=1;r=2*k;
while (l<r)
{
mid=(l+r)>>1;
if (cal(mid)>=k) r=mid;else l=mid+1;
}
printf("%I64d\n",l);
}
}