链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2440
中文题意很明确,要我们输入一个数k,求出第k个不是完全平方数的数。
解法就是求出1-x(一开始要设置一个大的上限 然后开始二分缩小区间直到找到答案)内的非完全平方数的个数,二分找到一个l=r时刚好非完全平方数的结果==k
需要的知识:二分法+容斥+莫比乌斯反演
AC代码如下:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> #define maxn 100005 typedef long long ll; using namespace std; int k; int mu[maxn]; int prime[maxn]; bool vis[maxn]; void getmu() { int tot=0; mu[1]=1; for(int i=2;i<=maxn;i++) { if(!vis[i]) { prime[++tot]=i; mu[i]=-1; } for(int j=1;prime[j]*i<=maxn;j++) { vis[prime[j]*i]=1; if(i%prime[j]==0) { mu[prime[j]*i]=0; break; } mu[prime[j]*i]=-mu[i]; } } } bool getans(ll x)//根据容斥+莫比乌斯奥特曼 { ll m=sqrt(x+0.5); ll ans=0; for(int i=1;i<=m;i++) { ans+=mu[i]*(x/(i*i)); } if(ans>=k)return true; return false; } int main() { int T; getmu(); scanf("%d",&T); while(T--) { scanf("%lld",&k); ll l=k,r=(ll)2e9; ll mid=(l+r)/2; ll ans=mid; while(l<r) { mid=(l+r)/2; if(getans(mid)) r=mid,ans=mid; else l=mid+1; } printf("%lld\n",ans); } }