数学方法

例1. \(1000=2\times 2\times 2\times 5\times 5\times 5\),从 \(6\) 个数中随便拿出若干个(\(0\sim 6\)),它们的乘积一定是 \(1000\) 的约数,问有多少种取法?这个答案即对应 \(1000\) 的约数个数。

解:使用乘法原理,将操作分为 \(2\) 步:

选定一定数量的 \(2\),个数可以是 \(0,1,2,3\);选法有 \(4\) 种。

选定一定数量的 \(5\),个数可以是 \(0,1,2,3\);选法有 \(4\) 种。

两步骤的方法数的乘积,即为答案:\(4\times 4=16\)。

例2. 求 \(28\) 的约数个数。

解:使用乘法原理,\(28=2^2\times 7\):

选定一定数量的 \(2\),个数可以是 \(0,1,2\);选法有 \(3\)​ 种。

选定一定数量的 \(7\),个数可以是 \(0,1\);选法有 \(2\) 种。

两步骤的方法数的乘积,即为答案:\(3\times 2=6\)。

例3. 求 \(156\) 的约数个数。

解:\(156=2^2\times 3\times 13\),约数个数为:\(3\times 2\times 2=12\)​。

代码

使用循环,依次找到 \(n\) 的每个质因数,求出该质因数有多少种选法,并将 \(n\) 中的这些质因数去掉,直到 \(n\) 为 \(1\)。

为了提高效率,我们在 \(i\ast i>n\) 时退出循环,如果此时 \(n>1\),则 \(n\) 必为素数,否则在之前的 \(i\) 中应该已经被分解了。

for (int i = 2; i*i <= n; ++i) {

if(n % i) continue;

int ct = 1;

while (n%i == 0) n /= i, ++ct;

ans *= ct;

}

if (n > 1) ans <<= 1;