【BZOJ2986】Non-Squarefree Numbers(莫比乌斯函数容斥)
大致题意: 求第\(n\)个含平方因子的数。
双倍经验
有一道和这题几乎完全一样的题目:【BZOJ2440】[中山市选2011] 完全平方数。
根据上面这道题的思想,我们先二分,然后计算这个数是第几个含平方因子的数,得到式子:
\[n-\sum_{i=1}^{\sqrt n}\mu(i)\times\lfloor\frac n{i^2}\rfloor=-\sum_{i=2}^{\sqrt n}\mu(i)\times\lfloor\frac n{i^2}\rfloor
\]
这样一来这道题就做完了。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define LL long long
using namespace std;
LL n;
class LinearSieve
{
private:
#define S 200000
int Pt,P[S+5],mu[S+5];
public:
I int operator [] (CI x) Con {return mu[x];}
I LinearSieve()//线性筛筛μ
{
mu[1]=1;for(RI i=2,j;i<=S;++i)
for(!P[i]&&(mu[P[++Pt]=i]=-1),j=1;j<=Pt&&i*P[j]<=S;++j)
if(P[i*P[j]]=1,i%P[j]) mu[i*P[j]]=-mu[i];else break;
}
}Mu;
I bool Check(Con LL& x)//验证
{
LL t=0;for(RI i=2;1LL*i*i<=x;++i) t-=Mu[i]*(x/i/i);//容斥
return t>=n;
}
int main()
{
LL l,r,mid;scanf("%lld",&n),l=1,r=n<<2;//初始化边界
W(l<r) Check(mid=l+r-1>>1)?r=mid:l=mid+1;//二分
return printf("%lld\n",r),0;
}
待到再迷茫时回头望,所有脚印会发出光芒