数论

算法

记号与定义

\(a\ mod\ p\)\(a\)\(p\) 的余数,等于 \(a - p \times \lfloor \frac{a}{p} \rfloor\)

\(a \mid b\)\(a\) 整除 \(b\)\(a\)\(b\) 的因数。

非平凡因子:除了 1 和 其 本身以外的因子。

素数判定

试除法

对于任意整数 \(n\),它的因数 \(d,\frac{n}{d}\) 总是成对出现,所以可以枚举 \([2,\sqrt{n}]\) 内的数,逐一判断是不是 \(n\) 的因数即可。

费马素性测试

属于概率性测试,根据费马小定理实现。

对于任意整数 \(n\),从 \([2,n-1]\) 中取数 \(a\) 作为基,如果满足 \(a^{n-1}\equiv 1(\mod n)\),则通过这一轮测试,如果所有测试均通过,那么认为 \(n\) 是一个素数。

Miller-Rabin 素性测试

费马素数测试还是会漏掉一些合数(满足费马小定理),这些数被称为费马伪素数。

所以就有了 Miller-Rabin 素性测试,这里引入了新的定理:

二次探测定理:对于一个质数 \(p\)\(x^2 \equiv1(mod\ p)\) 小于 \(p\) 的解只有两个,\(x_1=1,x_2=-1\)

proof: 移项得 \((x+1)(x-1) = 0 (mod\ p)\),又因为 \(p \in prime\), 所以 \(x+1,x-1\) 要么是 \(0\) 要么比 \(p\) 大,所以命题得证。

根据二次探测定理,如果 \(p\) 通过了费马检测,那么 \(p-1\) 会是个偶数(特判 \(2\)),所以就可以二次探测 \(a^{\frac{p-1}{2}} \equiv 1(mod\ p)\)\(a^{\frac{p-1}{4}} \equiv 1(mod\ p)\)……直到出现奇数。

也就是说我们只需要把 \(p-1\) 拆分为 \(u \times 2^t\),判断 \(a^u,a^{u \times 2},a^{u \times2^2}\) 解的情况即可,他们的值要么都是 \(1\),要么在第一次出现 \(p-1\) 后都是 \(1\) 并且之前没有 \(1\),注意到这里不能出现 \(p\) 的倍数,更不能在最后一个数上出现 \(p-1\),否则不满足费马小定理。
code:

int fsp(int x, int k, int p){
	int res = 1;
	while(k){
		if(k & 1) res = res * x % p;
		k >>= 1;
		x = x * x % p;
	}
	return res;
}

int bs[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
bool mrt(int n){
	if(n < 3 or (n & 1) != 1) return n == 2;
	int u = n - 1, cnt = 0;
	while((u & 1) != 1) u >>= 1, cnt++;
	for(auto i: bs){
		int tmp = fsp(i, u, n);
		if(tmp == 1 or tmp == n - 1 or tmp == 0) continue;
		for(int j = 1; j <= cnt; j++){
			tmp = tmp * tmp % n;
			if(tmp == n - 1 and j != cnt){tmp = 1; break;}
			if(tmp == 1) return 0;
		}
		if(tmp != 1) return 0;
	}
	return 1;
}

期望复杂度 \(O(\log n)\),同时也是个随机测试,但是在使用了上述几个底数后,在 OI 范围内出错的概率是 \(0\)

因数分解

试除法

同上,每次找出一个因子后给原数除去并计入答案即可,时间复杂度 \(O(\sqrt n)\)

Pollard rho 算法

首先介绍生日悖论:\(23\) 个人中,有两个人生日在同一天的概率超过 \(50%\),如果有 \(60\) 或更多的人,则概率大于 \(99%\)

考虑一个数 \(k,gcd(k,n)\) 肯定是 \(n\) 的一个因子,至于怎么取这个 \(k\), 考虑随机选取。

我们通过一个函数 \(f(x) = (x^2+c)\ mod\ n\) 生成随机数,为什么选他呢,因为一个性质:

\[\forall x\equiv y(\ mod\ p),f(x) \equiv f(y)(\ mod\ p), p \mid n \]

所以根据生日悖论,序列中不同的值数目 \(\leq \sqrt n\),把这个序列对 \(n\) 的最小非平凡因子 \(m\) 取模,期望不同的数个数 \(\leq n ^{\frac{1}{4}}\)

所以我们可以在期望 \(O(n^\frac{1}{4})\) 的时间内找到两个位置 \(i,j\) 使得 \(gcd(n,\mid x_i-x_j \mid)\)\(n\) 的一个非平凡因子。

每次随机选取 \(c\),期望复杂度 \(O(n^{\frac{1}{4}})\)

可以通过倍增优化求 gcd。

\[gcd(a,b) = gcd(ac,b) = gcd(ac\ mod\ b,b) \]

所以我们可以每隔一段时间集中处理 gcd 以优化算法。

code:LuoguP4718

#include <bits/stdc++.h>

#define LHK_AK_IOI true
#define int long long
const int mod = 998244353;
const __int128 O = 1;

using namespace std;

inline int read( ){
    int x = 0 ; short w = 0 ; char ch = 0;
    while( !isdigit(ch) ) { w|=ch=='-';ch=getchar();}
    while( isdigit(ch) ) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return w ? -x : x;
}

mt19937_64 rad(time(0));
int T;
int fac;

int fsp(int x, int k, int p){
	int res = 1;
	while(k){
		if(k & 1) res = O * res * x % p;
		k >>= 1;
		x = O * x * x % p;
	}
	return res;
}
int gcd(int a, int b){return (b == 0 ? a : gcd(b, a % b));}

int bs[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
bool mrt(int n){
	if(n < 3 or (n & 1) != 1) return n == 2;
	int u, cnt;
	cnt = __builtin_ctzll(n - 1);
	u = (n - 1) >> cnt;
	for(auto i: bs){
		int tmp = fsp(i, u, n);
		if(tmp == 1 or tmp == n - 1 or tmp == 0) continue;
		for(int j = 1; j <= cnt; j++){
			tmp = O * tmp * tmp % n;
			if(tmp == n - 1 and j != cnt){tmp = 1; break;}
			if(tmp == 1) return 0;
		}
		if(tmp != 1) return 0;
	}
	return 1;
}

int poll(int x){
	int s = 0, t = 0, val = 1;//s, t 是两个位置,val 是差值
	int c = rad( ) % (x - 1) + 1;// 常数
	for(int i = 1;; i <<= 1, s = t, val = 1){//倍增阶段
		for(int j = 1; j <= i; j++){// 步长
	 		t = (O * t * t + c) % x;// f(x)
	 		val = (O * val * abs(t - s)) % x;// gcd(ac % b, b) = gcd(ac, b)
		}
		int d = gcd(val, x);
	 	if(d > 1) return d;
	}
}

void rho(int x){
	if(x <= fac or x < 2) return;
	if(mrt(x)) return (void)(fac < x && (fac = x));//fac = max(fac, x);
	int p = x;
	while(p >= x) p = poll(x);
	while(x % p == 0) x /= p;
	rho(x); rho(p);
}

signed main( ){
	T = read();
	while(T--){
		int x = read( );
		fac = 0; rho(x);
		if(fac == x) printf("Prime\n");
		else printf("%lld\n",fac);
	}
	return (0-0);
}

同余

逆元

逆元,即满足 \(aa^{-1} \equiv 1 (mod\ b)\)\(a^{-1}\),通常有三种求法:

  1. 求解 \(ax \equiv 1 (mod\ b)\)\(ax + by = 1\);
  2. 费马小定理,快速幂求 \(a^{p-2} \equiv 1(mod\ p)\)
  3. 线性求逆元 \(inv_i = (p - \lfloor \frac{p}{i} \rfloor *inv_{p \ mod\ i})\ mod \ p\)

最大公约数(gcd)与最小公倍数(lcm)

更相减损法

\[gcd(a, b) = gcd(b, a - b) \]

proof:

\(d = gcd(a,b), a = k_1d, b = k_2d\)

\(a - b = k_1d - k_2d = (k_1 - k_2)d\)\(d \mid (k_1 - k_2)d\)

所以 \(d\)\(a - b\) 的因数,因为 \((k_1 - k_2) \nmid k_1\)\(d = gcd(a,b)\),所以 \(gcd(a, b) = gcd(b, a - b)\)

辗转相除法

\[gcd(a, b) = gcd(b, a \ mod \ b) \]

proof:根据更相减损法,\(gcd(a, b) = gcd(b, a - kb) = gcd(b, a\ mod\ b)\),定理得证。

关于 \(lcm\)\(lcm(a,b) = \frac{a \times b}{gcd(a, b)}\)

裴蜀定理

\(ax + by = gcd(a,b)\) 一定有解。

拓展欧几里得算法

求解二元一次不定方程:$ ax+by=c $

先求解 \(ax+by=gcd(a,b) = d\) 得到 \(x_0, y_0\) 两个解

继续同乘 \(\frac{c}{d}\) 得到\(\frac{acx_0}{d} +\frac{bcy_0}{d} = c\)

所以 \(ax+by = c\) 的解就是 \(x_1 = \frac{x_0c}{d}, y_1 = \frac{y_0c}{d}\)

所以构造通解 \(a(x_1+kb)+b(y_1-ka)=c\) 其中 \(ka\)\(kb\) 为整数

\(k\) 取道最小值的时候能保证相邻两个解之间相差 \(kb\)\(k a\)

所以 \(d_x=kb=\frac{b}{d},d_y=ka=\frac{a}{d},k=\frac{1}{d}\)

那么通解就是

\[\begin{cases} x = x_1 + sd_x\\ y = y_1 - s d_y\\ \end{cases} \]

如果要是有正整数解的话就是

\[\frac{-x_1}{d_x} < s <\frac{y_1}{d_x} \]

转化一下

\[\lceil\frac{-x_1+1}{d_x}\rceil \leq s \leq \lfloor\frac{y_1-1}{d_y} \rfloor \]

离散对数与剩余

BSGS 算法及其扩展

BSGS有 998244353 种读法你晓得吗

求同余方程\(A^x \equiv B \ (mod \ C)\) 的解,其中 \(A、C\) 互质。

暴力枚举 \(x\), 复杂度是 \(O(nlogn)\),考虑优化。

\(m = \lceil\sqrt{C}\rceil, r = x\ mod\ m\),有:

\[x = km-r\\A^{km-r} \equiv B\ (mod\ C)\\A^{km} \equiv BA^{r}\ (mod\ C) \]

我们就可以预处理出 \(BA^{r}\) 用哈希/桶维护一下,之后枚举 \(k\) 在表里找有没有对应的值就ok,时间复杂度\(O(\sqrt{C}\log{C})\)

但是当 \(A、C\) 不互质的时候 \(A\) 的逆元可能不存在,这时候就需要 \(EXBSGS\)

\(d = gcd(A,C)\), 如果 $\ d \nmid B\ $ 则无解,

之后原式就可以化成

\[A^{x-1}*\frac{A}{d} \equiv \frac{B}{d}\ (mod\ \frac{C}{d}) \]

所以

\[A^{x-1} \equiv \frac{B}{d} *(\frac{A}{d})^{-1}\ (mod\ \frac{C}{d}) \]

如果还不互质就继续减,最后就是

\[A^{x-cnt} \equiv \frac{B}{d} *(\frac{A}{d})^{-cnt}\ (mod\ \frac{C}{d}) \]

之后就可以 BGSG 做了。

二次剩余

\(x^k\equiv a(mod\ b)\) 成立的 \(a\) 称为模 \(b\)\(k\) 次剩余,否则称为 \(k\) 次非剩余。

二次剩余是 \(k = 2\) 时的特殊情况,相当于是模意义下的开根运算。

勒让德符号:

\[\left( \frac{a}{b} \right) = \begin{cases} 1,a \equiv x^2\mod\ b\\0,b\ |\ a\\-1,otherwise \end{cases} \]

Legendre 符号满足完全积性。

欧拉判别法则:

\[a^{\frac{p-1}{2}}\equiv \begin{cases} 1\mod b,\left( \frac{a}{b} \right) = 1\\ -1\mod b,\left( \frac{a}{b} \right) = -1 \end{cases} \]

根据欧拉判别法则我们能快速的判断一个数是否是模 \(p\) 的二次剩余。

二次互反律:

\[\forall p, q\in prime, p,q \not= 2\\ \left(\frac{p}{q}\right)\left(\frac{q}{p} \right) = (-1)^{\frac{p-1}{2}\frac{q-1}{2}} \]

Cipolla 算法

给定 \(a, b\) 求所有的 \(x\) 满足 \(x^2\equiv a\mod b\)

算法流程很简单,首先 rand 一个 \(x_0\) 使得 \(\left(\frac{x_0^2 - a}{b}\right) = -1\),此时令 \(w = \sqrt{x_0^2-a}\)

最后结果是 \(x \equiv (x_0 + w)^{\frac{b+1}{2}}(mod\ b)\)

考虑到模意义下的开根并没有意义,就像 \(\sqrt{-1}\) 一样,欸,\(\sqrt{-1}\) 不就是 \(i\) 嘛,所以我们考虑套用复数那套方法,引入一个新的域,在这个域内 \(w\) 存在,可以证明这个域确实是存在的。

最后的问题就是:为什么 \(x \equiv (x_0 + w)^{\frac{b+1}{2}}(mod\ b)\) 成立?这里浅证一下

两个前置结论:

\(w^b \equiv -w(mod\ b)\)

\((a+b)^k\equiv a^b+b^k(mod\ p)\)

读者自证不难。

\[\begin{split} x^2 &= (x_0 + w) ^{b + 1}\\ &= (x_0^b+w^b)(x_0+w)\\ &= (x_0-w)(x_0+w)\\ &= (x_0^2-(x_0^2-a))\\ &= a \end{split} \]

期望复杂度 \(O(log^2n)\),注意实现的时候需要手写”复数“。

定理

威尔逊定理及其扩展*

\((p-1)!\equiv -1\ (mod\ p), p \in prime\)

欧拉定理及其扩展

约定欧拉函数 \(\varphi(x)\) 表示 \([1,x]\) 之间有多少与 \(x\) 互质的数。

欧拉定理

\[gcd(a,m)=1,a^{\phi(m)}\equiv 1(\ mod\ m) \]

拓展欧拉定理:

\[a^b (mod\ p) = \begin{cases} a^b, &gcd(a,p) \neq 1,b \leq \varphi(p) \\ a^{b\ mod\ \varphi(p)}, &gcd(a,p) = 1\\ a^{b\ mod\ \varphi(p) + \varphi(p)}, &gcd(a,p) \not= 1 \end{cases} \]

费马小定理\(p \in prime, a^{p-1} \equiv 1\ (mod\ p)\),前提是 a 不是 p 的倍数,欧拉定理的特殊情况。

P4139 上帝与集合的正确用法

中国剩余定理(CRT)及其扩展

CRT:求解线性同余方程组:

\[\left\{\begin{matrix} x \equiv a_1(mod\ m_1)\\ x \equiv a_2(mod\ m_2)\\ ......\\ x \equiv a_k(mod\ m_k) \end{matrix}\right. \]

其中\(m_1,m_2...m_k\)互质。

约定:\(M_i = \frac{\Pi_{j = 1} ^ k m_j}{m_i}, t_i = M_i^{-1}\ mod \ m_i\)

考虑将整个方程组拆成k个方程组,构造一组特解:

\[\left\{\begin{matrix} x \equiv a_1(mod\ m_1)\\ x \equiv 0(mod\ m_2)\\ ......\\ x \equiv 0(mod\ m_k) \end{matrix}\right. \]

这个方程组有一个解为\(M_1 * t_1 * a_1\),那么把这 k 个方程组合并,原方程组的解就是:

\[x = \sum_{i = 1} ^ k a_iM_it_i \]

EXCRT\(m_1,m_2...m_k\) 不互质。
取其中两个同余方程

\[\left\{\begin{matrix} x \equiv a_1(mod\ m_1)\\ x \equiv a_2(mod\ m_2) \end{matrix}\right. \]

转化一下

\[\left\{\begin{matrix} x = a_1 + k_1m_1\\ x = a_2 + k_2m_2 \end{matrix}\right. \]

联立

\[a_1+k_1m_1 = a_2 + k_2m_2 \]

化简

\[k_1m_1 +(-k_2)m_2 = a_2 - a_1 \]

是一个形如 \(ax + by = c\) 的二元一次不定方程,用 \(exgcd\) 求解,注意这里存在无解的情况。

之后求得通解

\[k_1 = k_1'+ n\frac{m_2}{gcd(m_1,m_2)} \]

代回原式

\[x = a_1 + k_1'm_1 + n\frac{m_1m_2}{gcd(m_1,m_2)} \]

转化

\[x \equiv a_1 + k_1'm_1(mod\ lcm(m_1, m_2)) \]

由此我们又构造了一个形如 \(x \equiv a(mod\ m)\) 的同余方程,方程数量-1,以此类推,最后会得到这样一个柿子

\[x \equiv ans(mod\ lcm(m_1,m_1......m_n)) \]

就解决辣

Lucas 定理及其扩展*

lucas定理

\[C^m_n\ mod\ p = C^{\lfloor m/p\rfloor}_{\lfloor n/p\rfloor}C^{m\ mod\ p}_{n\ mod\ p}\ mod\ p,p \in prime \]

数论函数

数论函数基础

基本概念

积性函数:\(f(a) f(b) = f(ab),gcd(a,b) = 1\)

完全积性函数:\(f(a) f(b) = f(ab)\)

加性函数:\(f(a)+f(b) = f(ab),gcd(a, b) = 1\)

\(f*g=h\),若 \(f,g\) 都是积性函数,则 \(h\) 也是积性函数。

常见的数论函数

函数 性质&&定义
\(id_k(n)\) \(n^k\),\(id_1(n)\) 记作 \(id(n)\)
\(I(n)\) \(I(n) = 1\), 单位函数
\(\sigma_k(n)\) \(\sum_{d|n}d^k\)\(\sigma_0(n)\) 记作 \(d(n)\)
\(\mu(n)\) \(\begin{cases}1&n = 1\\0&n存在平方因子\\(-1)^{n的质因子数}&n不存在平方因子\end{cases}\)
\(\epsilon(n)\) \([n=1]\) ,单位元函数
\(\varphi(n)\) \([1,n]\) 中与 \(n\) 互质的数的个数

迪利克雷卷积

\((f*g)(n) = \sum_{d|n}f(d)g(\frac{n}{d})\)

常用的迪利克雷卷积:

卷积 证明 && 备注
\(\mu * id = \varphi\) 根据逆元可得
\(\varphi * I = id\) 证明2
\(I*I=\sigma\) 易证
\(\mu*I = \epsilon\) \(\mu\)\(I\) 的逆元,证明1

证明1

\(n = 1\) 时显然成立。

\(n\)\(k\) 个质因子。

\[\begin{split} \mu*1 &= \sum_{d|n}\mu(d)\\ &= \sum_{d=1}^k(-1)^d{k \choose d}\\ &= (1-1)^k\\ &= 0 \end{split} \]

证明2proof

筛法

参考 筛法

参考文献

https://oi-wiki.org/math/number-theory/basic/

https://www.luogu.com.cn/blog/command-block/mu-bi-wu-si-fan-yan-ji-ji-ying-yong

posted @ 2023-07-07 12:01  Kun_9  阅读(22)  评论(0编辑  收藏  举报