试除法求约数O(sqrt(n))
通过枚举较小的约数,并计算出成对的较大的约数
vector<int> get_divisors(int n){vector<int> res;for (int i = 1; i <= n / i; i ++) {if (n % i == 0) {res.push_back(i);if (i != n / i) {res.push_back(n / i);}}}sort(res.begin(), res.end());return res;}
约数个数和约数之和
把一个数进行质因子分解,
,对于每一项
,都有
种选择
- 因此,约数个数为
- 因此,约数之和为
约数个数
```cppinclude
include
using namespace std;
typedef long long LL; const int mod = 1e9 + 7;
int main()
{
int n;
unordered_map
<a name="tbOTP"></a>#### [约数之和](https://www.acwing.com/problem/content/873/)```cpp#include <iostream>#include <unordered_map>using namespace std;typedef long long LL;const int mod = 1e9 + 7;int main(){int n;unordered_map<int, int> hash;cin >> n;while (n --) {int x;cin >> x;for (int i = 2; i <= x / i; i ++) {while(x % i == 0) {hash[i] ++;x /= i;}}if (x > 1) {hash[x] ++;}}LL ans = 1;for (auto kv: hash) {int k = kv.first, v = kv.second;LL p = 1;for (int i = 0; i < v; i ++) {p = (p * k + 1) % mod;}ans = (ans * p) % mod;}cout << ans << endl;return 0;}
最大公约数
- 根据约数的定义可知,如果d能整除a并且d能整除b,则d能整除(xa + yb)
- 欧几里得定理gcd(a, b) == gcd(b, a % b)
- 证明,a % b = a - (a / b) b,由于a, b均为整数,因此a / b为整数,因此a % b = a - c b
- 对于a, b的公约数d,则d能整除a % b = a - c * b
- 反之亦然,对于b, a % b的公约数d,d能整除a = a - c b + c b
```cpp
include
using namespace std;
int gcd(int a, int b) { return b ? gcd(b, a % b): a; }
int main() { int n; scanf(“%d”, &n); while (n —) { int a, b; scanf(“%d%d”, &a, &b); cout << gcd(a, b) << endl; } return 0; } ```
