唯一分解定理
唯一分解定理指的是:对于任意一个>1的正整数,都可以以唯一的一种方式分解为若干质因数的乘积。
x
=
p
1
k
1
⋅
p
2
k
2
⋅
…
⋅
p
m
k
m
x = p_1^{k_1} \cdot p_2^{k_2} \cdot \ldots \cdot p_m^{k_m}
x=p1k1⋅p2k2⋅…⋅pmkm
这个式子中的p1,p2是类似2,3,5,7这样的质数。
将单个数字进行质因数方法是,从小到大枚举x的所有可能的质因子,最大枚举到sqrt(x),每遇到一个可以整除的数字i,就不断进行除法直到除尽。最后如果还有x>1,说明还有一个较大的质因子。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
vector<pair<int, int>> v;
int main() {
int x;
cin >> x;
// Enumerate all possible prime factors
for (int i = 2; i <= x / i; ++i) {
// If it doesn't divide, skip
if (x % i) continue;
// If it divides, it must be a prime factor (due to the nature of enumeration from small to large)
// Count represents the exponent of the current prime factor (i)
int cnt = 0;
// Keep dividing until it is no longer divisible
while (x % i == 0) {
cnt++;
x /= i;
}
v.push_back({i, cnt});
}
// If x is greater than 1, it means x itself is a prime factor
if (x > 1) {
v.push_back({x, 1});
}
// Print the prime factors and their exponents
for (const auto &i : v) {
cout << i.first << ' ' << i.second << '\n';
}
return 0;
}
约数个数定理
通过某个数字的唯一分解:
x
=
p
1
k
1
⋅
p
2
k
2
⋅
…
⋅
p
m
k
m
x = p_1^{k_1} \cdot p_2^{k_2} \cdot \ldots \cdot p_m^{k_m}
x=p1k1⋅p2k2⋅…⋅pmkm
我们可以求出x的约数(因数)个数,如果学过线性代数或者有向量相关的知识的话,可以理解为将不同的质因子看作是不同的向量空间或基底,不同质因子之间互不干扰。
也就是说p1的指数的取值是[0,k1]共(k1+1)个,p2,p3…亦然,所以x的约数的个数就是 (k1+1)*(k2+1)*…*(km+1),即:
d
(
x
)
=
∏
i
=
1
m
(
k
i
+
1
)
d(x) = \prod_{i=1}^{m}(k_i + 1)
d(x)=i=1∏m(ki+1)
阶乘约数
思路:100!阶乘太大,不能直接求出再求正约数。可以用唯一分解定理和约数个数定理来求约数个数。
#include<iostream>
using namespace std;
const int N = 1e2 + 5;
int a[N];
void f(int x){
for(int i=2;i<=x/i;i++){
if(x%i)continue;
int cnt = 0;
while(x%i==0){
cnt++;
x/=i;
}
a[i]+=cnt;
}
if(x>1)a[x]++;
}
int main(){
for(int i = 1;i<=100;i++)f(i);
long long ans =1;
for(int i=1;i<=100;i++)ans*=(a[i]+1);
cout<<ans<<'\n';
return 0;
}
求值
#include<iostream>
using namespace std;
int check(int x) {
int cnt = 0;
for(int i=1;i*i<=x;i++){
if(x%i==0){
if(i==x/i)cnt++;
else cnt+=2;
}
}
return cnt == 100;
}
int main() {
for(int i=1; ;i++){
if(check(i)){
cout<<i<<'\n';
break;
}
}
return 0;
}