文章目录
- AcWing 869. 试除法求约数
- 题目链接
- 思路
- CODE
- AcWing 870. 约数个数
- 题目链接
- 思路
- CODE
- AcWing 871. 约数之和
- 题目链接
- 思路
- CODE
- AcWing 872. 最大公约数
- 题目链接
- 思路
- CODE
AcWing 869. 试除法求约数
题目链接
https://www.acwing.com/activity/content/problem/content/938/
思路
基于算术基本定理,从最小质数开始往上除,直到不含这个因数,而和数都是由比它小的质数相乘得来,所以所有约束都是质数。
CODE
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>using namespace std;int n;vector<int> get_divided(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;
}int main()
{cin >> n;while (n -- ){int a;scanf("%d", &a);auto res = get_divided(a);for(auto t : res) cout << t << ' ';puts("");}
}
AcWing 870. 约数个数
题目链接
https://www.acwing.com/activity/content/problem/content/939/
思路
还是基于算术基本定理,一个数可以分解为唯一因式: K = p 1 a 1 + p 2 a 2 + . . . + p i a i K = p1^{a1} + p2^{a2} + ... + pi^{ai} K=p1a1+p2a2+...+piai
那么约数的个数就是公式: ( a 1 + 1 ) ( a 2 + 1 ) . . . ( a i + 1 ) (a1 + 1)(a2 + 1)...(ai + 1) (a1+1)(a2+1)...(ai+1)
CODE
#include<vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>using namespace std;typedef long long ll;const int mod = 1e9 + 7;
int n;int main()
{cin >> n;unordered_map<int, int> primes;while (n -- ){int a;scanf("%d", &a);for(int i = 2; i <= a / i; ++i){while(a % i == 0){a /= i;primes[i]++;}}if(a > 1) primes[a]++;}ll res = 1;for(auto t : primes) res = res * (t.second + 1) % mod;cout << res << endl;
}
AcWing 871. 约数之和
题目链接
https://www.acwing.com/activity/content/problem/content/940/
思路
还是基于算术基本定理: K = p 1 a 1 + p 2 a 2 + . . . + p i a i K = p1^{a1} + p2^{a2} + ... + pi^{ai} K=p1a1+p2a2+...+piai由这个因式我们可以得到以下公式: N = ( p 1 0 + p 1 1 + . . . + p 1 a 1 ) ( p 2 0 + p 2 1 + . . . p 2 a 2 ) . . . ( p i 0 + p i 1 + . . . + p i a i ) N = (p1^0 + p1^1 +...+ p1^{a1})(p2^0 + p2^1 + ... p2 ^ {a2})...(pi ^ 0 + pi ^1 + ...+ pi^{ai}) N=(p10+p11+...+p1a1)(p20+p21+...p2a2)...(pi0+pi1+...+piai)这个公式展开就是每项约数的和。
详细推导可以参考以下视频:约数个数与约数之和
CODE
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>using namespace std;typedef long long ll;const int mod = 1e9 + 7;
int n;int main()
{cin >> n;unordered_map<int, int> primes;while (n -- ){int a;scanf("%d", &a);for(int i = 2; i <= a / i; ++i){while(a % i == 0){a /= i;primes[i]++;}}if(a > 1) primes[a]++;}ll ans = 1;for(auto p : primes){ll a = p.first, b = p.second;ll res = 1;while(b--) res = (res * a + 1) % mod;ans = ans * res % mod;}cout << ans << endl;
}
AcWing 872. 最大公约数
题目链接
https://www.acwing.com/activity/content/problem/content/941/
思路
辗转相除法
具体证明请看 VCR
CODE
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;int gcd(int a, int b){return b ? gcd(b, a % b) : a;
}int main()
{int n;cin >> n;while(n--){int a, b;scanf("%d%d", &a, &b);cout << gcd(a, b) << endl;}
}