欧几里得算法:

欧几里得算法是求最大公约数的算法:是辗转相除法的具体实现

  1. int gcd(int x, int y) {
  2. if (y == 0) return x;
  3. else {
  4. gcd(y, x % y);
  5. }
  6. }

无需比较x, y的大小

扩展欧几里得算法:

扩展欧几里得算法是用于求逆元的。如果d与m互质—>(cd) % m == 1,那么c是d关于模m的逆元。
由题意:c _
d == k m + 1;形如a x + b _y = 数。
变形:c
d + k * m == 1;
已知:d,m—>求c的可能取值

  1. void exgcd(int a, int b, int& x, int& y) {
  2. if (b == 0) {
  3. x = 1; y = 0;
  4. }
  5. else {
  6. exgcd(b, a % b, y, x);
  7. y -= a / b * x;
  8. }
  9. }
  10. exgcd(d, m, x, y);
  11. c = (x%m + m)%m;

同余理论:

(a + b) % m == (a % m + b %m) % m;
(a _ b) % m == (a % m b %m)%m;_

快速乘理论:

因为 a * b 可能会爆long long—>所以将乘法转换为加法进行计算。

  1. int mul(int a, int b) {
  2. int ans = 0;
  3. while (b) {
  4. if (b & 1) {
  5. ans = (ans + a);
  6. }
  7. a += a;
  8. b >>= 1;
  9. }
  10. return ans;
  11. }

因为快速乘算法一般还涉及余数的处理问题,所以(a * b) % m的快速乘版本:

  1. int Qmul(int a, int b, int m) {
  2. int ans = 0;
  3. while (b) {
  4. if (b & 1) {
  5. ans = (ans % m + a % m) % m;
  6. }
  7. a = (a % m + a % m) % m;
  8. b >>= 1;
  9. }
  10. return ans;
  11. }

快速幂原理:

因为a^b极易超时或者范围爆炸,所以快速乘

  1. int Qpower(int a, int b) {
  2. int ans = 1;
  3. while (b) {
  4. if (b & 1) {
  5. ans *= a;
  6. }
  7. a *= a;
  8. b >>= 1;
  9. }
  10. return ans;
  11. }

取余情况下的快速幂算法:—>余数为m

  1. int Qpower(int a, int b, int m) {
  2. int ans = 1;
  3. while (b) {
  4. if (b & 1) {
  5. ans = ((ans % m) * a % m) % m;
  6. }
  7. a = (a % m * a % m) % m;
  8. b >>= 1;
  9. }
  10. return ans;
  11. }