【笔记】基础数论(待更新)
数论问题
裴蜀定理
使 \(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 ^ {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)\) 下面,得到 :
之后两边乘上 \(i ^ {- 1},r ^ {- 1}\) 得到 :
这样我们就可以退出一串数的逆元了。
inv[1] = 1;
for(int i = 2;i < p;i ++) {
inv[i] = (p - p / i) * inv[p % i] % p;
}
阶乘求逆元
有如下一个递推关系 :
所以,我们可以求出 \(n!\) 的逆元,之后从后往前递推,就可以求出 \(1 \cdots n\) 的所有数的逆元了。
递推式即为 : \(inv[i + 1] * (i + 1) = inv[i]\)。
根据这个也可以得出 \(\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}\),则 :
证明 : 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
欧拉定理
欧拉函数已经说完了,与其紧密相连的是欧拉定理 :
扩展欧拉定理
证明 : Link

浙公网安备 33010602011771号