【BZOJ2440】【中山市选2011】—完全平方数(莫比乌斯函数+容斥原理)
题意:求第个无平方因子数
考虑到第个不好求
二分一个数,计算以内的无平方因子数
由于容斥原理
质数的平方的所有倍数+2个质数之积的平方的所有倍数-3个质数之积的平方的所有倍数+4个……
这是个简单的容斥很好证明
考虑一下每个的符号,质数为,2个质数为,3个质数为,4个质数为
就是莫比乌斯函数!!
由于大于的数的平方已经大于了,所以我们只需要枚举以内的数
而一个数的平方在内的出现次数为
所以
整除分块即可
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();
int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
}
#define ll long long
const int N=100005;
int mu[N],pr[N],vis[N],sum[N],tot,n,k;
inline void init(){
mu[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])pr[++tot]=i,mu[i]=-1;
for(int j=1;j<=tot&&i*pr[j]<N;++j){
vis[i*pr[j]]=1;
if(i%pr[j]==0)break;
mu[i*pr[j]]=-mu[i];
}
}
for(int i=1;i<N;++i)sum[i]=sum[i-1]+mu[i];
}
inline bool check(int x){
int p=sqrt(x),ans=0;
for(int i=1,nxt;i<=p;i=nxt+1){
nxt=min((int)sqrt(x/(x/(i*i))),p);
ans+=(x/(i*i))*(sum[nxt]-sum[i-1]);
}
return ans>=n;
}
int main(){
int T=read();init();
while(T--){
n=read();int ans=0;
int l=1,r=n*2;
while(l<=r){
int mid=((ll)l+(ll)r)>>1;
if(check(mid))ans=mid,r=mid-1;
else l=mid+1;
}
cout<<ans<<'\n';
}
}