涉及到算术基本定理和约数定理的题目经常需要求质因数及其幂次,下面是一种高效的求法,和一种复杂度稍高但是简单实用的方法。
#include <iostream>
#include <cstring>
using namespace std;
int primePower[101];
const int N = 100;
int power[N + 1]; //power[i]是质因子i的幂次
void findPrimeFactorPower() {
int x = N; //x不断缩小,直至不再能分解
for (int j = 2; j * j <= x; j++) {
//若x<j*j,说明连j^2都分解不出来了,更别谈j^3,(j+1)^2,(j+1)^3...所以此时退出循环,最多剩下一个质数(j或j+1或j+2..或j*j-1)
while (x % j == 0) {
x /= j;
power[j]++;
}
}
if (x > 1) //此时如果仍然大于1,则剩下一个质因子
power[x]++;
}
void show(){
//展示所有质因数的幂次
cout << N << "=";
bool isFirst = true;
for (int i = 1; i <= N; i++) {
if (power[i]) {
if (isFirst) {
isFirst = false;
} else {
cout << "+";
}
cout << i << "^" << power[i];
}
}
}
问题:求一个正整数的约数个数(根据约数基本定理,等于各个质因数幂次+1的乘积)
这里发现,并不需要判断质数,大大降低了复杂度,核心原因是合数可以分解为质数乘积,所以从i=2开始,每次对n把i除尽,也就意味着n后续不可能是2(或者别的质数)的倍数了,所以循环种所有i为合数的情况都被直接跳过了。例如
12
2
2
=
3
\frac{12}{2^2}=3
2212=3,后续3不可能再是4的倍数了。
//计算一个数各个质因数幂+1的乘积
int func(long long n){
int res=1;
int i=2;
while(n>1){
int count=0;
while(n%i==0){
n/=i;
count++;
}
res*=(count+1);
i++;
}
return res;
}