BZOJ 2440 完全平方數-莫比烏斯函式
阿新 • • 發佈:2019-02-09
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();
}
}