【笔记】基础数论(待更新)

数论问题

裴蜀定理

Link

使 \(ax + by = c ,x \in Z ^ *,y \in Z ^ *\) 成立的充要条件是 \(\gcd(a,b) | c\)

证明 :

\(s = \gcd(a,b)\) ,显然可得 \(s | a \ \ \And\And \ \ s | b\)

\(\because x , y \in Z ^ *\)
\(\therefore s | ax \ \ ,s | by\)

显然要使得之前的式子成立,则必须满足 \(s\)\(a\)\(b\) 的公约数的倍数。

又因为 \(x\)\(y\) 是正整数。

所以 \(c\) 必然是 \(a\),\(b\) 最大公约数的倍数。

因此,证得该定理成立。

\(Code\)

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
inline int read()
{
	int s = 0, f = 0;char ch = getchar();
	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
	return f ? -s : s;
}
int Gcd(int a,int b) {return b ? Gcd(b,a % b) : a;}
signed main()
{
  n = read();
  int ans = 0,num;
  for(int i = 1;i <= n;i ++) {
    num = read();
    num = num < 0 ? -num : num;
    ans = Gcd(ans,num);
  }
  printf("%d",ans);
  return 0;
}

乘法逆元

\(x * y \equiv 1 (\bmod \ \ p)\),并且 \(x\)\(y\) 互质,那么我们就能定义: \(y\)\(x\) 的逆元,记为 \(x ^ {- 1}\),所以我们也可以称 \(y\)\(x\)\(\bmod \ \ b\) 意义下的倒数。

对于分数的形式,像 \(\dfrac{x}{y} \bmod p\),我们只需要求出 \(y\)\(\bmod \ \ p\) 下的逆元,在乘上分母 \(x\) ,最后 \(\bmod \ \ p\) 即可。

费马小定理求逆元

其实就是用了个快速幂。

\(p\) 为素数,\(x\) 为正整数,且 \(x\)\(p\) 互质。 则有 \(x^{p-1} \equiv 1 (\bmod \ \ {p})\)

这个式子右边刚好为 \(1\)

之后再代入原来的式子 :

\[x * y \equiv 1 (\bmod \ \ p) \\ x * y \equiv x ^ {p - 1} (\bmod \ \ p) \\ y \equiv x ^ {p - 2} (\bmod \ \ p) \]

之后套一个快速幂求出 \(x ^ {p - 2} (\bmod \ \ p)\) 就是逆元了。

int KSM(int x,int y,int mod)
{
  x %= mod;int ans = 1;
  while(y) {
    if(y & 1) ans = ans * x % mod;
    x = x * x % mod;
    y >>= 1;
  }
  return ans;
}
signed main()
{
  int x,mod;
  scanf("%d%d",&x,&mod);
  int ans = KSM(x,mod - 2,mod);
}

拓展欧几里得

这个就是利用拓欧求解线性同余方程 \(x*y \equiv z \pmod {p}\)\(z = 1\) 的情况。我们就可以转化为解 \(a*x + b*y = 1\) 这个方程。

之后就是求这个方程的解就可以了。

另外,这个方法还可以在 \(p \bot x\) 的是候使用,更为简便。

貌似效率挺高的。

void Exgcd(int a,int b,int &x,int &y) 
{
  if(!b) x = 1,y = 0;
  else Exgcd(b,a % b,y,x), y -= a / b * x;
}
signed main()
{ 
  int x,y,a,mod;
  Exgcd(a,mod,x,y);
  x = (x % mod + mod) % mod;
  int ans = x;
}

线性求逆元

这个适用于求一连串的数字的逆元的时候,因为其他的方法都比这个方法要慢。

首先显然 \(1 ^ {- 1} \equiv 1 (\bmod \ \ p)\)

之后我们设 \(p = k * i + r,(1 < r < i < p)\) 也就是 \(k\)\(p / i\) 的商,而 \(r\) 是余数。

之后我们放在 \((\bmod \ \ p)\) 下面,得到 :

\[k * i + r \equiv 0 (\bmod \ \ p ) \]

之后两边乘上 \(i ^ {- 1},r ^ {- 1}\) 得到 :

\[k * 1 * r ^ {- 1} + i ^ {- 1} * 1 \equiv 0 (\bmod \ \ p) \\ k * r ^ {- 1} + i ^ {- 1} \equiv 0 (\bmod \ \ p) \\ i ^ {- 1} \equiv -k * r ^ {- 1} (\bmod \ \ p) \\ i ^ {- 1} \equiv - \left \lfloor \frac{p}{i} \right \rfloor * (p \ \ \bmod \ \ i) ^ {- 1} (\bmod \ \ p) \]

这样我们就可以退出一串数的逆元了。

inv[1] = 1;
for(int i = 2;i < p;i ++) {
    inv[i] = (p - p / i) * inv[p % i] % p;
}

阶乘求逆元

有如下一个递推关系 :

\[inv[i + 1] = \dfrac{1}{(i + 1)!} \\ inv[i + 1] * (i + 1) = \dfrac{1}{i!} = inv[i] \]

所以,我们可以求出 \(n!\) 的逆元,之后从后往前递推,就可以求出 \(1 \cdots n\) 的所有数的逆元了。

递推式即为 : \(inv[i + 1] * (i + 1) = inv[i]\)

根据这个也可以得出 \(\dfrac{1}{i !} (\bmod \ \ p)\) 的取值 :

\[\dfrac{1}{i !} \times (i - 1)! = \dfrac{1}{i} (\bmod \ \ p) \]

int KSM(int x,int y,int mod)
{
  x %= mod;int ans = 1;
  while(y) {
    if(y & 1) ans = ans * x % mod;
    x = x * x % mod;
    y >>= 1;
  }
  return ans;
}
signed main()
{
  c[0] = 1;//阶乘
  for(int i = 1;i <= n;i ++) c[i] = c[i - 1] * i % mod;
  f[n] = KSM(c[n],mod - 2,mod);
  for(int i = n - 1;i >= 1;i --) f[i] = (f[i + 1] * (i + 1)) % mod;
  for(int i = 1;i <= n;i ++) f[i] = (f[i] * c[i - 1]) % mod;//逆元
}

欧拉函数

欧拉函数指表示的是小于等于 \(n\)\(n\) 互质的数的个数,记作 \(\varphi(n)\)

在算数基本定理中,\(n = p_1 ^ {c_1} p_2 ^ {c_2}p_3 ^ {c_3} \cdots p_m ^ {c_m}\),则 :

\[\varphi(n) = n * \frac{p_1 - 1}{p_1} * \frac{p_2 - 1}{p_2} * \cdots * \frac{p_m - 1}{p_m} = n * \prod(1 - \frac{1}{p}) \]

证明 : Link

根据欧拉函数的计算式,我们只需分解质因数,即可顺便求出欧拉函数。

int phi(int n)
{
  int ans = n;
  for(int i = 2;i <= sqrt(n);i ++) {
    if(n % i == 0) {
      ans = ans / i * (i - 1);
      while(n % i == 0) n /= i; 
    }
  }
  if(n > 1) ans = ans / n * (n - 1);
  return ans;
}

一些性质 :

  • 欧拉函数是积性函数

积性的意思是:如果有 \(\gcd(a,b) = 1\),那么 \(\varphi(a \times b) = \varphi(a) \times \varphi(b)\)

特别的,当 \(n\) 是一个奇数的时候 \(\varphi(2n) = \varphi(n)\)

  • \(\forall n > 1\)\(1 \cdots n\) 中与 \(n\) 互质的数的和为 \(n * \varphi(n) / 2\)

证明 :

因为 \(\gcd(n,x) = \gcd\),所以与 \(n\),不互质的数 \(x\)\(n - x\) 成对出现,平均值为 \(n / 2\)。因此,与 \(n\) 互质的数的平均值也是 \(n / 2\),进而证明结论。

  • \(p\) 为质数,若 \(p ^ 2 | n\),则 \(\varphi(n) = \varphi(n / p) * p\)

证明 :

\(p | n\)\(p ^ 2 | n\),则 \(n,n / p\) 包含相同的质因子,只是 \(p\) 的指数不同。直接把 \(\varphi(n)\)\(\varphi(n / p)\) 按照欧拉函数的计算公式算出,二者相除,商为 \(p\),所以结论成立。

  • \(p\) 为质数,若 \(p ^ 2 \not| \ \ n\),则 \(\varphi(n) = \varphi(n / p) * (p - 1)\)

\(p | n\)\(p ^ 2 \not| \ \ n\),则 \(p,n / p\) 互质,由 \(\varphi\) 是积性函数得到 \(\varphi(n) = \varphi(n / p) * \varphi(p)\),而 \(\varphi(p) = p - 1\),所以结论成立。

  • \(\sum_{d|n} \varphi(d) = n\)

这个不太会证,证明详见 Link

欧拉定理

欧拉函数已经说完了,与其紧密相连的是欧拉定理 :

\[\gcd(a,m) = 1 \to a ^ {\varphi(m)} \equiv 1\pmod p \]

扩展欧拉定理

\[a ^ b \equiv \begin{cases} a ^ {b \ \ \bmod \ \ \varphi(p)}, & \gcd(a,p) = 1\\ a ^ b, & \gcd(a,p) \not= 1,b < \varphi(p) \pmod p\\ a ^ {b \ \ \bmod \ \ \varphi(p) + \varphi(p)}, & \gcd(a,p) \not= 1,b > \varphi(p) \end{cases}\]

证明 : Link

posted @ 2021-04-14 19:51  Ti_Despairy  阅读(85)  评论(1)    收藏  举报