【BZOJ2986】Non-Squarefree Numbers(莫比乌斯函数容斥)

点此看题面

大致题意: 求第(n)个含平方因子的数。

双倍经验

有一道和这题几乎完全一样的题目:【BZOJ2440】[中山市选2011] 完全平方数

根据上面这道题的思想,我们先二分,然后计算这个数是第几个含平方因子的数,得到式子:

[n-sum_{i=1}^{sqrt n}mu(i) imeslfloorfrac n{i^2} floor=-sum_{i=2}^{sqrt n}mu(i) imeslfloorfrac n{i^2} floor ]

这样一来这道题就做完了。

代码

#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
",r),0;
}
原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ2986.html