[莫比乌斯函数][二分] Bzoj 2440 完全平方数
Description
小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些
数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而
这丝毫不影响他对其他数的热爱。
这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一
个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了
小X。小X很开心地收下了。
然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?
题解
- 二分答案,将问题转换为求[1,m]种有多少个无平方因子数
- 没有平方因子不就是μ(i)!=0
- 根据容斥原理,满足要求的ans=n-只有一个质数因子次数大于等于2的个数+只有2个质数因子大于等于2的个数-...
代码
1 #include <cmath> 2 #include <cstdio> 3 #include <iostream> 4 #define ll long long 5 using namespace std; 6 const ll N=100010,inf=(1<<31)-1; 7 ll T,n,l,r,ans,mobius[N],p[N],bz[N]; 8 bool check(ll x) { ll r=0; for (ll i=1;i<=sqrt(x);i++) r+=mobius[i]*x/(i*i); return r>=n; } 9 int main() 10 { 11 scanf("%lld",&T),mobius[1]=1; 12 for (ll i=2;i<=N;i++) 13 { 14 if (!bz[i]) mobius[i]=-1,p[++p[0]]=i; 15 for (ll j=1;j<=p[0]&&i*p[j]<=N;j++) 16 { 17 bz[i*p[j]]=1; 18 if (i%p[j]) mobius[i*p[j]]=-mobius[i]; else { mobius[i*p[j]]=0; break; } 19 } 20 } 21 for (;T;T--) 22 { 23 scanf("%lld",&n),l=1,r=ans=inf; 24 while (l<=r) 25 { 26 ll mid=l+r>>1; 27 if (check(mid)) ans=mid,r=mid-1; else l=mid+1; 28 } 29 printf("%lld\n",ans); 30 } 31 }