BZOJ2440: [中山市选2011]完全平方数dizh

来源:互联网 发布:java 内置des加密 编辑:程序博客网 时间:2024/04/27 15:48

链接: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 100005typedef 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);}}




1 1
原创粉丝点击