BZOJ 2440 完全平方数-莫比乌斯函数
1.n的不大确定+f(n)([1,n]中不是平方数的倍数的数的个数)递增 -> 二分
2.容斥原理:f(x)=1的倍数-一个质数的倍数+2个质数乘积的倍数-… ;
f(x)=sigma(mu[i]*floor(x/(i*i))) ,1<=i<=floor(sqrt(x))
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 500000
#define INF 2000000000
typedef long long LL;
LL mu[MAXN+10],prime[MAXN+10],cntpr,k;
bool isprime[MAXN+10];
void CalMobius(LL n)
{
memset(mu,0,sizeof mu);
memset(isprime,0,sizeof isprime);
cntpr=0;
mu[1]=1;
for(LL i=2;i<=n;i++){
if(!isprime[i]){
prime[++cntpr]=i;
mu[i]=-1;
}
for(LL j=1;prime[j]*i<=n&&j<=cntpr;j++){
isprime[prime[j]*i]=true;
if(i%prime[j]==0){
mu[prime[j]*i]=0;
break;
}
mu[prime[j]*i]=-mu[i];
}
}
}
LL Quary(LL x)
{
LL side=sqrt(x+0.5),ret=0;
for(LL i=1;i<=side;i++)
ret+=mu[i]*(x/(i*i)); //也不要加floor装逼了,这个也会导致TLE
return ret;
}
void partition()
{
LL l=1,r=INF,mid,ans;
while(l<r){
mid=(l+r)/2;
if(Quary(mid)>=k){
r=mid;
ans=mid;
}
else
l=mid+1;
}
printf("%lld\n",ans);
}
int main()
{
LL T;
scanf("%lld",&T);
CalMobius(MAXN); //注意MAXN不要开大了,虽然是线性筛,但就是这个害得我TLE
while(T--){
scanf("%lld",&k);
partition();
}
}