对OI Wiki数论相关内容的整理

PART0 OI Wiki

引用自官网:

OI Wiki 致力于成为一个免费开放且持续更新的知识整合站点,大家可以在这里获取关于 编程竞赛 (competitive programming) 有趣又实用的知识,我们为大家准备了竞赛中的基础知识、常见题型、解题思路以及常用工具等内容,帮助大家更快速深入地学习编程竞赛。

PART1 简介

在 OI/ACM 的各种比赛中,常常会有数学题的出现。
这些数学题以数论、排列组合、概率期望、多项式为代表,可以出现在几乎任何类别的题目中。
举几个栗子:

  1. 多项式可以优化卷积形式的背包,可以做一些字符串题。
  2. 很多 DP 类型的题都可以结合排列组合/概率期望。

NOIP 中有可能会考察的知识点

然而 NOIP 可能考察更多的知识点,这里只是利用之前的题总结出来的,考过或者考的概率比较大的知识点。
NOIP 对数学的考察还处在一个比较简单的范围。

  1. 进制相关——通常是利用进制优化一些问题
  2. 位运算——状压常用
  3. 高精度——不包括需要利用多项式的高精度
  4. 整除性质——\(gcd\),欧拉函数,费马小定理
  5. 同余相关——\(exgcd\),逆元,中国剩余定理
  6. 概率期望——概率 DP,以及有可能用到高斯消元解决的概率 DP
  7. 排列组合——杨辉三角,二项式定理,卢卡斯定理,卡特兰数

PART2 最大公约数

最大公约数即为 Greatest Common Divisor,常缩写为 gcd

素数一节中,我们已经介绍了约数的概念。

一组数的公约数,是指同时是这组数中每一个数的约数的数。而最大公约数,则是指所有公约数里面最大的一个。

那么如何求最大公约数呢?我们先考虑两个数的情况。

两个数的

如果我们已知两个数 \(a\)\(b\) ,如何求出二者的最大公约数呢?

不妨设 \(a > b\)

我们发现如果 \(b\)\(a\) 的约数,那么 \(b\) 就是二者的最大公约数。
下面讨论不能整除的情况,即 \(a = b \times q + r\) ,其中 \(r < b\)

我们通过证明可以得到 \(\gcd(a,b)=\gcd(b,a \bmod b)\) ,过程如下:


\(a=bk+c\) ,显然有 \(c=a \bmod b\) 。设 \(d|a\ \ \ d|b\) ,则 \(c=a-bk\) \(\frac{c}{d}=\frac{a}{d}-\frac{b}{d}k\) 由右边的式子可知 \(\frac{c}{d}\) 为整数,即 \(d|c\) 所以对于 \(a,b\) 的公约数,它也会是 \(a \bmod b\) 的公约数。

反过来也需要证明

\(d|b\ \ \ d|(a \bmod b)\) ,我们还是可以像之前一样得到以下式子 \(\frac{a\bmod b}{d}=\frac{a}{d}-\frac{b}{d}k\) \(\frac{a\bmod b}{d}+\frac{b}{d}k=\frac{a}{d}\) 因为左边式子显然为整数,所以 \(\frac{a}{d}\) 也为整数,即 \(d|a\) ,所以 \(b,a\bmod b\) 的公约数也是 \(a,b\) 的公约数。

既然两式公约数都是相同的,那么最大公约数也会相同

所以得到式子 \(\gcd(a,b)=\gcd(b,a\bmod b)\)

既然得到了 \(\gcd(a, b) = \gcd(b, r)\) ,这里两个数的大小是不会增大的,那么我们也就得到了关于两个数的最大公约数的一个递归求法。

int gcd(int a, int b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}

递归至 b==0 (即上一步的 a%b==0 ) 的情况再返回值即可。

如果两个数 \(a\)\(b\) 满足 \(\gcd(a, b) = 1\) ,我们称 \(a\)\(b\) 互质。

多个数的

那怎么求多个书的最大公约数呢?显然答案一定是每个数的约数,那么也一定是每相邻两个数的约数。我们采用归纳法,可以证明,每次取出两个数求出答案后再放回去,不会对所需要的答案造成影响。

PART3 EXGCD - 扩展欧几里得定理

目的:求 \(ax+by=\gcd(a,b)\) 的一组可行解

证明

\(ax_1+by_1=\gcd(a,b)\)

\(bx_2+(a\bmod b)y_2=\gcd(b,a\bmod b)\)

由欧几里得定理可知: \(\gcd(a,b)=\gcd(b,a\bmod b)\)

所以 \(ax_1+by_1=bx_2+(a\bmod b)y_2\)

又因为 \(a\bmod b=a-(\lfloor\frac{a}{b}\rfloor\times b)\)

所以 \(ax_1+by_1=bx_2+(a-(\lfloor\frac{a}{b}\rfloor\times b))y_2\)

\(ax_1+by_1=ay_2+bx_2-\lfloor\frac{a}{b}\rfloor\times by_2=ay_2+b(x_2-\lfloor\frac{a}{b}\rfloor y_2)\)

因为 \(a=a,b=b\) ,所以 \(x_1=y_2,y_1=x_2-\lfloor\frac{a}{b}\rfloor y_2\)

\(x_2,y_2\) 不断代入递归求解直至 GCD(最大公约数,下同)为 0 递归 x=1,y=0 回去求解。

int Exgcd(int a, int b, int &x, int &y) {
  if (!b) {
    x = 1;
    y = 0;
    return a;
  }
  int d = Exgcd(b, a % b, x, y);
  int t = x;
  x = y;
  y = t - (a / b) * y;
  return d;
}

函数返回的值为 GCD,在这个过程中计算 \(x,y\) 即可

猜你喜欢

转载自www.cnblogs.com/water-lift/p/10502769.html
OI
今日推荐