[莫比乌斯函数][二分] 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 }

 

posted @ 2019-08-08 10:05  BEYang_Z  阅读(198)  评论(0编辑  收藏  举报