所有约数——试除法——O(sqrt(n))
vector<int> res;
for(int i = 1; i <= n / i; i++)
{
if(i % n == 0)
{
res.push_back(i);
if(i != n / i) res.push_back(n / i);
}
sort(res.begin(), res,end());
}
接下来两个算法都是基于算数基本定理(对就是那个用素数唯一拆分所有数字的东西)
约数个数
//一个数完全分解成素数乘积之后 把每个出现过素数的指数统统加一然后乘在一起就是答案
long long res = 1;
for(auto prime : primes) res *= (prime.second + 1);
约数之和
long long res = 1;
for(auto prime : primes)
{
int p = prime.first, a = prime.second;
LL t = 1;
while(a--) t = (t * p + 1);
res = res * t;
}
欧几里得算法 又名 辗转相除
//关键 gcd(a, b) = gcd(b, a % b)
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
//其实__gcd(a, b)更香