我们回想一道小学奥数题。问从1~120以内能被2或3或5整除的自然数有几个?这涉及到了容斥原理的一些知识。假设答案是k。那么我们反问,第k个能被2或3或5整除的自然数是谁?因为120恰好就是一个能被2或3或5整除的自然数,所以第k个这样的数一定就是120.
所以,我们对于这道题,我们就是希望猜测这样一个数M,使得1~M之间能被a或b或c整除的自然数恰好有n个。言下之意,1~(M-1)之间能被a或b或c整除的自然数就只有n-1个了。对于这样的数,显然我们又可以利用二分法的策略去猜:反馈依据就是M以内能被a或b或c整除的自然数的个数,通过与n的比较来调整搜索区间。
最后如何写count(M)来计算M以内能被a或b或c整除的自然数的个数的个数呢?依据容斥原理:
count(M) = M/a+M/b+M/c-M/lcm(a,b)-M/lcm(a,c)-M/lcm(b,c)+M/lcm(lcm(a,b),c);
其中最小公倍数:lcm(a,b) = a*b/gcd(a,b)
,最大公约数则用辗转相除法:
ll gcd(ll a, ll b)
{
if (b==0)
return a;
return gcd(b, a%b);
}