总结:
1、用到素数的时候,先把线性筛函数写出来,然后再根据题目需求进行相应的更改。
线性筛得记下来:
int prime[max_n + 5] = {0};
void init() {
for (int i = 2; i <= max_n; i++) {
if (!prime[i]) prime[++prime[0]] = i;
for (int j = 1; j <= prime[0]; j++) {
if (prime[j] * i > max_n) break;
prime[prime[j] * i] = 1;
if (i % prime[j] == 0) break;
}
}
return ;
}
对于任意正整数N,设它的质因数分解为
(p1^n1)*(p2^n2)*......*(pk^nk),其中n1, n2, ..., nk > 0, p1, p2, ..., pk 为素数
它的所有约数个数为(n1 + 1) *(n2 + 1) *...... *(nk + 1),记作F(n)
若C=A*B,且A,B互素,那么C的约数个数F(C)为多少?
F(C) = F(A) × F(B) ——因为互素,所以没有相同的素因子,因此做笛卡尔积;
枚举n,则第n个三角形数的约数个数F(n)为
F(n) = F(n(n+1)/2)
= F(n/2) × F(n+1) 当n为偶数
= F(n) × F((n+1))/2) 当n为奇数
用线性筛的代码框架,实现了求每个正整数的约数个数;
但是由于其中添加了一个while循环,破坏了整个代码的“优美性”;
有没有快速的方法,知道现在正整数最小素因子的幂次是多少?
有用记录式,而非计算式,这样就是稳稳地O(n)时间复杂度了。
开一个新的数组,记录最小的素因子的次幂,即可省略while来计算cnt了。