数论学习笔记

取模的性质

性质一:\(a\%b=a-\lfloor\frac ab\rfloor\cdot b\)

证明:

\(a\div b=c……d\),则 \(a=bc+d\)

c++ 中,有 \(a/b=c,a\%b=d\)。将 \(c,d\) 代入,得:

\[a=b\cdot\lfloor\frac ab\rfloor+a\%b \]

移项,得 \(a\%b=a-\lfloor\frac ab\rfloor\cdot b\)

证毕。


性质二:\((a+b)\%p=(a\%p+b\%p)\%p\)

证明:

\(a\div p=a_1……a_2,b\div p=b_1……b_2\),则 \(a=pa_1+a_2,b=pb_1+b_2\)

于是有:

\[\begin{aligned} a_1&=a/p\qquad a_2=a\%p \\b_1&=b/p\qquad b_2=b\%p \end{aligned} \]

因此,\((a+b)\%p=(pa_1+a_2+pb_1+b_2)\%p=(a_2+b_2)\%p=(a\%p+b\%p)\%p\)。「乘 \(p\) 的直接消掉」

证毕。


性质三:\((a-b)\%p=(a\%p-b\%p)\%p\)

证明:

还是用性质二的证明中设出来的 \(a_1,a_2,b_1,b_2\)

\((a-b)\%p=(pa_1+a_2-pb_1-b_2)\%p=(a_2-b_2)\%p=(a\%p-b\%p)\%p\)

证毕。


性质四:\((a\times b)\%p=(a\%p\times b\%p)\%p\)

证明:

还是用性质二的证明中设出来的 \(a_1,a_2,b_1,b_2\)

\[\begin{aligned} (a\times b)\%p &=[(pa_1+a_2)\times(pb_1+b_2)]\%p \\&=(pa_1\times pb_1+pa_1\times b_2+pb_1\times a_2+a_2\times b_2)\%p \\&=(a_2\times b_2)\%p \\&=(a\%p\times b\%p)\%p \end{aligned} \]

证毕。


性质五:c++ 的取模运算中,被除数与余数符号相同。

即:若 \(a\%b=c\),则 \(a、c\) 同号,\(c\) 的符号与 \(b\) 无关。

证明:语法特性,无需证明。




gcdlcm

定理 & 推导

「首先有定义:\(\gcd(a,b),\text{lcm}(a,b)\) 分别表示正整数 \(a,b\) 的最大公约数和最小公倍数,特殊地,规定 \(\gcd(0,a)=a\)

定理一:若 \(a>b\),则 \(\gcd(a,b)=\gcd(a-b,b)\)

证明:

\(\gcd(a,b)=x\),则 \(\exist a',b'\in \N^+\),使得 \(a=a'x,b=b'x\)\(\gcd(a',b')=1\)

将其带入,得:\(\gcd(a-b,b)=\gcd(a'x-b'x,b'x)=x\gcd(a'-b',b')\)

现在只需证明 \(x=x\gcd(a'-b',b')\),即 \(\gcd(a'-b',b')=1\) 即可。

不妨设 \(\gcd(a'-b',b')=y\),则 \(\exist c,d\in \N^+\),使得 \(a'-b'=cy,b'=dy\)\(\gcd(c,d)=1\)

将二式相加,得:\(a'=a'-b'+b'=cy+dy\),故 \(\gcd(a',b')=\gcd(cy+dy,dy)=y\gcd(c+d,d)\)

由于 \(\gcd(a',b')=1\),可以得到:\(y\gcd(c+d,d)=1\)

因为都是正整数,所以 \(y=\gcd(c+d,d)=1\),故 \(\gcd(a'-b',b')=1\),故 \(\gcd(a,b)=\gcd(a-b,b)\)

证毕。


定理二:若 \(a>b\),则 \(\gcd(a,b)=\gcd(a\%b,b)\)「辗转相除法」

证明:

由定理一很容易得到:

\[\gcd(a,b)=\gcd(a-b,b)=\gcd(a-2b,b)=...=\gcd(a-kb,b) \]

其中 \(a-kb<b\)

易得 \(k=\lfloor\frac ab\rfloor\),由于 \(a-\lfloor\frac ab\rfloor\cdot b=a\%b\),故 \(a-kb=a\%b\)

证毕。


定理三:\(\text{lcm}(a,b)=\frac{ab}{\gcd(a,b)}\)

证明:

\(\gcd(a,b)=x\),则 \(\exist a',b'\in \N^+\),使得 \(a=a'x,b=b'x\)\(\gcd(a',b')=1\)

于是 \(ab=a'x\cdot b'x,\text{lcm}(a',b')=a'b'\)

\[\begin{aligned} \text{lcm}(a,b)&=\text{lcm}(a'x,b'x) \\&=x\cdot \text{lcm}(a',b') \\&=xa'b' \\&=\frac{a'x\cdot b'x}x \\&=\frac{ab}{\gcd(a,b)} \end{aligned} \]

证毕。


gcd 代码「递归式」

由定理二可以写出递归代码:

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

gcd 代码「迭代式」

发现每次调用 \(\gcd\) 函数时,要保证第二个参数小于等于第一个参数,因此只需每次迭代将当前参数互换「直接用异或可以避免引入第三个参数」,即可避免递归。

迭代代码:

inline int gcd(int a,int b)
{
    while(b) a%=b,a^=b^=a^=b;
    return a;
}

gcd 代码时间复杂度简单分析

一次递归/迭代中,\(\gcd(a,b)\) 可以转化为 \(\gcd(b,a\%b)\),可以看作其中 \(b\) 不变,\(a\) 变为 \(a\%b\)

那么如何具体算出 \(a\) 减少了多少呢?

我们都知道,\(a\div b=c……d\) 可以写为 \(a=b\times c+d\) 的形式。

不妨设 \(a\div b=c……d\),则 \(a\%b=d\)

要具体分析 \(d\) 的大小,可以对 \(b\) 的大小进行分类讨论:

  1. \(b>\frac a2\),显然 \(c=0,d=a-b<\frac a2\)
  2. \(b\le\frac a2\),显然 \(d<b\le\frac a2\)

经过一次迭代,\(a\) 的规模减小了至少一半,而经过两次迭代,\(b\) 的规模也减少了至少一半。

因此,无论何种情况,经过两次迭代,要求解的规模一定小于等于原来的一半,最坏运行次数不会超过 \(2\log_2\min\{a,b\}。\)

因此,可以不太严谨地说,辗转相除法求解 gcd 的时间复杂度近似为 \(\log\min\{a,b\}\)。「反正严谨的证明我也不会略略略


lcm 代码

根据定理三,闭着眼都可以写出代码:

inline int lcm(int a,int b)
{
    return a*b/gcd(a,b);
}



莫比乌斯反演

数论函数:定义域为正整数的函数称为数论函数。

积性函数:如果 \(\forall a、b,(a,b)=1,f(ab)=f(a)f(b)\),这样的数论函数称为积性函数。

常见的数论函数:

  • 欧拉函数「如果 \((a,b)=1\),则有 \(\varphi(ab)=\varphi(a)\varphi(b)\)

    • 莫比乌斯函数

    • 除数函数 「用 \(d_k(n)\) 表示,其值等于所有 \(n\) 的因子的 \(k\) 次方之和」

      \(e.g.\)

      \(d_2(12)=1^2+2^2+3^2+4^2+6^2+12^2=219+d_1(5)=1^1+5^1=6,d_1(7)=1^1+7^1=8\)
      \(\because(5,7)=1\)
      \(\therefore d_1(35)=d_1(5*7)=d_1(5)*d_1(7)=6*8=48\)
      验证一下:
      \(d_1(35)=1^1+5^1+7^1+35^1=48\)
      (和欧拉函数有些类似)

  • 完全积性函数:如果 \(\forall a、b,f(ab)=f(a)f(b)\),这样的数论函数称为完全积性函数。

    • 常见的完全积性函数:\(f(x)=x\)



FFTNTT

posted @ 2021-09-16 16:58  凌云_void  阅读(42)  评论(0编辑  收藏  举报