求第k个非完全平方数
先二分一下,问题变成1~x有多少个非完全平方数,知道平方数的集合,可以容斥一下
(为了叙述方便,下文一个数可代表其平方的倍数的集合)
被一个集合包含的只有质数,被两个集合包含的是质因数个数为2的数……而且所有考虑的数都不含平方因子,可以发现和
μ
一样,被考虑进去的数的
所以预处理一下
μ
,每次询问
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 1010000;
int mou[maxn],p[maxn],pri;
bool v[maxn];
ll count(ll x)
{
ll ret=0;
ll q=sqrt(x);
for(ll i=1;i<=q;i++)
{
if(mou[i]) ret += mou[i]*(x/(i*i));
}
return ret;
}
ll up=1644934081;
ll find_(ll l,ll r,ll x)
{
while(l<=r)
{
ll mid=(l+r)>>1;
ll c=count(mid);
if(c>=x)r=mid-1;
else l=mid+1;
}
return r+1;
}
int main()
{
mou[1]=1;
for(int i=2;i<maxn;i++)
{
if(!v[i]) p[++pri]=i,mou[i]=-1;
for(int j=1;j<=pri&&p[j]*i<maxn;j++)
{
int k=p[j]*i;
v[k]=true; mou[k]=-mou[i];
if(i%p[j]==0) { mou[k]=0; break; }
}
}
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
ll x;scanf("%lld",&x);
printf("%lld\n",find_(x,up,x));
}
return 0;
}