【题解】
本题中完全平方数不考虑1
在1~k*2中二分答案:对于x,只需求出1~x中有多少个数不是完全平方数的倍数
由容斥原理:
1~x中 不是完全平方数的倍数 的数的个数 = x - 是至少1个质数n次方的数的个数 + 是至少2个质数n次方的数的个数 - 是至少3个质数n次方的数的个数 …
其中的系数1的正负刚好与 因式中多次出现的质数种类数的奇偶性一致,因此系数可以用类似莫比乌斯函数的方法求得
而对于每个x,枚举质数只需枚举到sqrt(n)
【代码】
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int no[100005],pri[100005],mu[100005];
int k;
int order(int x)
{
int sq=(int)sqrt(x+0.5),i,ans=0;
for(i=1;i<=sq;i++)
ans+=x/(i*i)*mu[i];
return ans;
}
int judge(int x)
{
int sq=(int)sqrt(x+0.5),i;
for(i=1;pri[i]<=sq;i++)
if(x%(pri[i]*pri[i])==0) return 0;
return 1;
}
void erfen(int left,int right)
{
long long t;
int mid,ord;
while(1)
{
t=((long long)left+(long long)right)/2LL;
mid=(int)t;
ord=order(mid);
if(ord==k&&judge(mid)==1)
{
printf("%d\n",mid);
return;
}
if(ord>=k) right=mid-1;
else left=mid+1;
}
}
int main()
{
int T,i,j,p=0;
mu[1]=1;//预处理:求莫比乌斯函数
for(i=2;i<=100000;i++)
{
if(no[i]==0)
{
pri[++p]=i;
mu[i]=-1;
}
for(j=1;j<=p&&pri[j]*i<=100000;j++)
{
no[pri[j]*i]=1;
if(i%pri[j]==0) break;
mu[pri[j]*i]=-mu[i];
}
}
scanf("%d",&T);
for(;T>0;T--)
{
scanf("%d",&k);
erfen(1,2*k);
}
return 0;
}