您的位置:首页 > 其它

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

2016-05-07 21:13 429 查看
链接: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);
}
}


[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息