image.png

Primes and factors素数和因子

image.png

Number of primes

image.png

One interesting class of prime:
image.png

试除法判断素数

  1. bool is_prime(int x)
  2. {
  3. if (x < 2) return false;
  4. for (int i = 2; i <= x / i; i++)
  5. if (x %i == 0) return false;
  6. return true;
  7. }

分解质因子

  1. void divide(int x)
  2. {
  3. for (int i = 2; i <= x / i; i++)
  4. if (x % i == 0)
  5. {
  6. int s = 0; // 计数器,记录个数
  7. while (x % i == 0) x /= i, s++;
  8. cout << i << ' ' << s << endl;
  9. }
  10. if (x > 1) cout << x << ' ' << 1 << endl;
  11. puts("");
  12. }

唯一分解定理

image.png

朴素筛法O(nlogn)

  1. void get_primes(int n)
  2. {
  3. for (int i = 2; i <= n; i++)
  4. {
  5. if (!st[i])
  6. {
  7. primes[cnt++] = i;
  8. }
  9. for (int j = i + i; j <= n; j += i) st[j] = true;
  10. }
  11. }

image.png

埃式筛法O(n) O(nloglogn)

  1. void get_primes(int n)
  2. {
  3. for (int i = 2; i <= n; i++)
  4. {
  5. if (st[i]) continue;
  6. primes[cnt++] = i;
  7. for (int j = i + i; j <= n; j += i)
  8. st[j] = true;
  9. }
  10. }

image.png

线性筛 O(n)

  1. // 核心:n只会被他的最小质因子筛掉
  2. void get_primes(int n)
  3. {
  4. for (int i = 2; i <= n; i++)
  5. {
  6. if (!st[i]) primes[cnt++] = i;
  7. for (int j = 0; primes[j] <= n / i; j++)
  8. {
  9. st[primes[j] * i] = true;
  10. if (i % primes[j] == 0) break;
  11. }
  12. }
  13. }

image.png

约数个数

image.png

  1. #include <iostream>
  2. #include <unordered_map>
  3. using namespace std;
  4. typedef long long LL;
  5. const int mod = 1e9 + 7;
  6. int main()
  7. {
  8. int n;
  9. cin >> n;
  10. unordered_map<int, int> primes;
  11. while (n--)
  12. {
  13. int x;
  14. cin >> x;
  15. for (int i = 2; i <= x / i; i++)
  16. while (x % i == 0)
  17. {
  18. x /= i;
  19. primes[i] ++;
  20. }
  21. if (x > 1) primes[x]++;
  22. }
  23. LL res = 1;
  24. unordered_map<int, int>::iterator it;
  25. for (it = primes.begin(); it != primes.end(); it++)
  26. res = res * ((*it).second + 1) % mod;
  27. cout << res << endl;
  28. return 0;
  29. }

image.png

约数之和

image.png

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <unordered_map>
  4. using namespace std;
  5. typedef long long LL;
  6. const int mod = 1e9 + 7;
  7. int main()
  8. {
  9. int n;
  10. cin >> n;
  11. unordered_map<int, int> primes;
  12. while (n--)
  13. {
  14. int x;
  15. cin >> x;
  16. for (int i = 2; i <= x / i; i++)
  17. while (x % i == 0)
  18. {
  19. x /= i;
  20. primes[i]++;
  21. }
  22. if (x > 1) primes[x]++;
  23. }
  24. LL res = 1;
  25. for (auto prime : primes)
  26. {
  27. int p = prime.first, a = prime.second;
  28. LL t = 1;
  29. while (a--) t = (t * p + 1) % mod;
  30. res = res * t % mod;
  31. }
  32. cout << res << endl;
  33. return 0;
  34. }

image.png

欧几里得算法(辗转相除法)

image.png
image.png

  1. int gcd(int a, int b) {
  2. if (b == 0)
  3. return a;
  4. return gcd(b, a % b);
  5. }
  6. int gcd(int a, int b)
  7. {
  8. return b ? gcd(b, a % b) : a;
  9. }
  10. int gcd(int a, int b) {
  11. int tmp;
  12. while(b != 0) {
  13. tmp = b;
  14. b = a % b;
  15. a = tmp;
  16. }
  17. return a;
  18. }

IMG_2557.PNGIMG_2558.PNGIMG_2559.PNGIMG_2560.PNG

Modular arithmetic模运算

image.png

核心:随时取模

大纲要求

•【3】整除、因数、倍数、指数、质数、合数、同余等概念

•【3】唯一分解定理

•【3】欧几里得算法(辗转相除法)

•【4】埃氏筛法和线性筛法求素数