TheSquareRootDilemma
作者:徐明宽
关键词:简单数论 平方数 平方因子 枚举 分块 线性筛 莫比乌斯函数 次线性复杂度(一道easy弄了这么多关键词……)
题目简述
输入两个正整数,输出有多少组有序数对满足且是整数。 保证。
分析
因为,所以是整数等价于是完全平方数。(证明:如果是完全平方数,那么显然为整数;如果不是完全平方数,那么为无理数,自然也是无理数,也就不是整数了。)
我们可以将和中的所有平方因子除去以后所得的数分别记为和(即:将分解质因数,设 (其中是质数,是非负整数,是正整数),令;由计算的方法类似)。那么因为是完全平方数,所以也是完全平方数。于是对于任意质数,有,又因和都没有平方因子,所以不整除,于是。所以。同理,。于是有。
算法一
分析到这里,我们可以得出一个算法:枚举,由于是的约数中最大的完全平方数,我们可以通过枚举不超过的所有完全平方数看是不是的约数(当然直接把分解质因数也行)来计算出,也就得到了,那么一定是的完全平方数倍,枚举这个倍数,这样就能找出所有有序数对了。时间复杂度是,空间复杂度是。
算法二
换一种思路,考虑枚举,计算有多少组对应的有序数对。如果我们枚举了(也就是)(注意只能取不包含平方因子的数),那么只需让为完全平方数,并且即可满足要求。当确定时,可以取的值的数量分别与不超过和的完全平方数个数相同,即分别为和。
现在的问题就变成了找出所有,即不超过的所有不包含平方因子的数。我们可以用筛法求出来,即把所有(大于的)完全平方数的倍数筛掉,剩下的就是不包含平方因子的数。这样做的时间复杂度是。然后枚举,将对应的和的数量乘起来(即)计入答案即可。总时间复杂度与空间复杂度都是。
算法三
下面来探讨一下复杂度低于线性的算法。
根据算法二,答案 。
注意到根据容斥原理,的前缀和(注意区别于,这里的指的是任意一个正整数)可以在较低的时间复杂度内计算,而的取值个数又不是很多,所以可以考虑分块,即对于的每种取值计算对应的一段的区间和。
(下面为了方便描述,不妨设)
假设我们用线性筛预处理了以内的的前缀和以及的前缀和。那么对于从到(for(a = S; a <= N; a++)
),从下降到,从下降到,所以时一共只有不超过种取值。
对于任意(注意区别于,这里的指的是任意一个正整数),计算时,一共只有不超过种取值(因为要么,要么),所以如果,就能在的时间内计算。
因此,如果,这个算法的总时间复杂度为 。
综上,当时(这道题中和是同级的,一般不会出现这种情况),取,可得时间复杂度;否则,取(此时有),可得时间复杂度。(更直观地,当时,时间复杂度为)