学习笔记:原根、指标、NTT、分治FFT/NTT、牛顿迭代

阶与原根

若正整数 \(m, \ a\),满足 \((a, m) = 1\),则使 \(a^n\equiv 1 \pmod m\) 的最小正整数 \(n\) 称为 \(a\)\(m\) 的阶,记作 \(\delta_m(a)\)

\(\delta_7(1) = 1, \ \delta_7(2) = 3, \ \delta_7(3) = 6\)

原根

\(\delta_m(a) = \varphi(m)\),则称 \(a\)\(m\) 的一个原根。

欧拉定理:若 \((a, m) = 1\),则 \(a^{\varphi(m)}\equiv 1\pmod m\)

阶的性质

假设 \((a, m) = 1, \ \delta = \delta_m(a)\),则

  1. \(a^0, a^1, \dots, a^{\delta - 1}\) 在模 \(m\) 意义下两两不同。

    证明:

    如果存在 \(a^x \equiv a^y \pmod m, \ x < y \le \delta - 1\)

    \(a^{y - x} \equiv 1\),且 \(y - x < \delta\),与阶的最小性矛盾。

  2. \(a^{\gamma}\equiv a^{\gamma'} \pmod m \iff \gamma \equiv \gamma'\pmod \delta\)

  3. \(\delta \mid \varphi(m)\)

    证明:

    \(\varphi(m) = q\delta + r, \ (0 \le r < \delta)\)

    如果 \(r > 0\),则 \(a^{q\delta + r} \equiv a^{r} \equiv a^{\varphi(m)}\equiv 1 \pmod m\),则有 \(r < \delta\),与 \(\delta_m(a) = \delta\) 矛盾。

    所以 \(r = 0\)

  4. \(m \in\mathbb{N^*}, \ a, b\in \mathbb{Z}, \ (a, m) = (b, m) = 1\),则

    \[\delta_m(ab) = \delta_m(a)\delta_m(b) \]

    的充要条件为 \((\delta_m(a), \delta_m(b)) = 1\)

  5. \(k\in \mathbb{N}, \ m \in \mathbb{N^*}, \ a\in \mathbb{Z}, \ (a, m) = 1\),则

    \[\delta_m(a^k) = \dfrac{\delta_m(a)}{(\delta_m(a), k)} \]

    证明:

    注意到:

    \[\begin{aligned} & a^{k\delta_m(a^k)}=(a^k)^{\delta_m(a^k)}\equiv 1 \pmod m \\ \implies & \delta_m(a)\mid k\delta_m(a^k) \\ \implies & \dfrac{\delta_m(a)}{\left(\delta_m(a),k\right)}\mid\delta_m(a^k) \end{aligned} \]

    另一方面,由 \(a^{\delta_m(a)}\equiv 1 \pmod m\),可知:

    \[(a^k)^{\frac{\delta_m(a)}{(\delta_m(a),k)}}=(a^{\delta_m(a)})^{\frac{k}{(\delta_m(a),k)}}\equiv 1 \pmod m \]

    故:

    \[\delta_m(a^k)\mid\dfrac{\delta_m(a)}{(\delta_m(a),k)} \]

    综合以上两点,得:

    \[\delta_m(a^k)=\dfrac{\delta_m(a)}{(\delta_m(a),k)} \]

原根的存在与判定

原根的存在定理

只有模 \(2,\ 4,\ p^a,\ 2p^a\)\(p\) 是奇质数)存在原根。

原根的判定定理

\(m > 1\)\(g\) 为正整数且 \((g, m) = 1\)。则 \(g\)\(m\) 的原根当且仅当对于任意 \(\varphi(m)\) 的质因子 \(q_i\)\(g^{\varphi(m)/q_i} \not\equiv 1 \pmod m\)

证明:如果 \(\delta < \varphi(m)\)\(\delta \mid \varphi(m)\),则一定存在一个 \(q_i\) 使得 \(\delta \mid\varphi(m) / q_i\)

原根个数

\(m\) 有原根,则它原根的个数为 \(\varphi(\varphi(m))\)

证明:

\(m\) 有原根 \(g\),则:

\[\delta_m(g^k)=\dfrac{\delta_m(g)}{\left(\delta_m(g),k\right)}=\dfrac{\varphi(m)}{\left(\varphi(m),k\right)} \]

所以若 \(\left(k,\varphi(m)\right)=1\),则有:\(\delta_m(g^k)=\varphi(m)\),即 \(g^k\) 也是模 \(m\) 的原根。

而满足 \(\left(\varphi(m),k\right)=1\)\(1\leq k \leq \varphi(m)\)\(k\)\(\varphi(\varphi(m))\) 个。所以原根就有 \(\varphi(\varphi(m))\) 个。

P6091 【模板】原根submission

指标(离散对数)

定义

对于质数 \(p\),假设 \(g\)\(p\) 的一个原根,则 \(g^0, \ g^1, \dots, g^{p - 2}\) 在模 \(p\) 意义下是 \(1, 2, \dots, p - 1\) 的一个排列。

假设对于 \(x \in [1, p)\)\(g^c\equiv x \pmod p\),则称 \(x\) 的指标为 \(c\),记作 \(\operatorname{ind}(x) = c\)(或 \(\operatorname{ind}_g(x) = c\))。

性质

对于任意 \(x, y \in [1, p)\),存在

\[\begin{aligned} \operatorname{ind}(xy) &= \operatorname{ind}(x) + \operatorname{ind}(y)\pmod {\varphi(p)}\\ \\ \operatorname{ind}(x^c) &= c\operatorname{ind}(x)\pmod {\varphi(p)}\\ \end{aligned} \]

类似于实数运算中的对数,因此指标亦称离散对数。

BSGS (baby step giant step)

给定质数 \(p\),求最小满足 \(g^c \equiv x \pmod {p}\) 的非负整数 \(c\) 的值。

\(c = aB + b\),其中 \(B = \lceil\sqrt{p}\rceil\)

因为 \(c < \varphi(p) = p - 1\),所以 \(a, \ b < B\)

  1. BS:枚举 \(b = 0, \ 1, \ \dots, B - 1\),将 \(xg^{b}\) 计入哈希表。

  2. GS:枚举 \(a = 1, \ 2, \ \dots, B\),若存在 \(g^{aB} = xg^b\),则最小满足条件的 \(c = aB - b\)

这样枚举会漏掉 \(c = 0\) 的解,单独特判即可。

最小性证明:

对于 \(xg^b \bmod p\) 相同的 \(b\),大的会在哈希表中覆盖小的,从而使 \(aB - b\) 最小。

\(B > b\),所以 \(a\) 对答案的贡献大于 \(b\),从小到大枚举 \(a\) 使答案最小。

【模板】BSGS

例题

Discrete Roots

题意:给出两个质数 \(p, k\) 和一个整数 \(a\),求 \(x^k = a \pmod p\) 的所有解。

\[\begin{aligned} &\operatorname{ind}(x^k) = k\operatorname{ind}(x) = \operatorname{ind}(a) \pmod{\varphi(p)}\\ \\ &k\operatorname{ind}(x) \equiv\operatorname{ind}(a)\pmod{\varphi(p)}\\ \\ &x \equiv g^{\operatorname{ind}(x)} \pmod p \end{aligned} \]

所以只需处理 \(p\) 的原根以及 \(a\) 的指标,中间的同余方程可用 exgcd 求解。

特判 \(a = 0\) 的情况。

submission

快速数论数论变换(NTT)

即把 FFT 中 \(\mathbb{C}\) 上的运算变成 \(\mathbb{Z}_p\) 上的运算。

  • 假设素数 \(p\) 满足 \(p = r2^l + 1\)\(g\)\(p\) 的原根。

  • \(g_n = g^{\frac{p - 1}{n}}\) 替代 \(\omega_n\)

  • \(g_{2n}^{2k} \equiv g_n^k \pmod p, \ (2n < 2^l)\)

  • \(g_{2n}^{n} \equiv -1 \pmod p, \ (2n < 2^l)\)

    \(g_{2n}^n = g^{\frac{p - 1}{2}}\)

    由于 \((g^{\frac{p - 1}{2}})^2 \equiv g^{p - 1} \equiv 1\pmod p\),所以 \(g_{2n}^n\) 只可能同余 \(1\)\(-1\)

    又因为 \(g\) 为原根,\(\delta_{p}(g) = p - 1\)

    \(g^{\frac{p - 1}{2}} \equiv 1\) 则与阶的最小性矛盾,所以 \(g^{\frac{p - 1}{2}}\equiv-1\pmod p\)

  • \(\sum_{k = 0}^{n - 1}g_{n}^{ik}g_{n}^{-kj} \equiv \begin{cases} n & i = j\\ 0 & i \neq j \end{cases}\pmod p\),其中 \(i, j \in [0, n)\)

优点:快,精确。

限制:模数要满足 \(p = 2^l + 1\)

常见模数:

  • \(65537 = 2^{16} + 1, \ g = 3\)

  • \(998244353 = 119 \cdot 2^{23} + 1, \ g = 3\)

  • \(1004535809 = 479 \cdot 2^{21} + 1, \ g = 3 \quad > 10^{9}\)

  • \(4179340454199820289 = 29 \cdot 2^{57} + 1, \ g = 3 \quad> 4\cdot 10^{18}\)

A * B Problem Plussubmission

分治 FFT(NTT)

  1. 在模 \(998244353\) 意义下,计算 \(f(x) = \prod (x - a_i)\) 的各项系数。

    • 计算 \([l, mid]\) 之积。

    • 计算 \([mid + 1, r]\) 之积

    • \([l, mid]\)\([mid + 1, r]\) 相乘。

    时间复杂度 \(O(n\log^2n)\)

  2. 在模 \(998244353\) 意义下,计算 \(f(x) = \prod f_i(x)\) 的各项系数,其中 \(\sum\deg(f_i(x)) \le 10^5\)

    可以和上题一样分治。

    也可以按照次数维护一个优先队列,每次相乘当前最小的两个,即一棵哈夫曼树。

例题

P4721 【模板】分治 FFT

题意:给定 \(g_1 \dots g_{n - 1}\),求 \(f_0\dots f_{n - 1}\),满足 \(f_0 = 1\)\(f_i = \sum_{j = 1}^ig_jf_{i - j}\)

后式是一个卷积的形式,考虑分治。

假设当前正在处理区间 \([l, r]\)

  • 递归 \([l, mid]\),求出 \(f_l\dots f_{mid}\)
  • 计算 \(f_l\dots f_{mid}\)\(f_{mid + 1}\dots f_r\) 的贡献。
  • 递归 \([mid + 1, r]\)

具体怎么求贡献?

\(\forall i \in [l, mid], \ a_{i - l} = f_l\)

\(\forall i \in [1, r - l], \ b_{i - 1} = g_i\)

对于 \(\forall i \in [mid + 1, r]\),加上 \([x^{i - l - 1}]A*B\) 的贡献。

void solve(int l, int r) {
	if(l == r) {
		return;
	}
	int mid = l + r >> 1;
	solve(l, mid);
	
	bit = 0;
	while((1 << bit) < (r - l)) ++ bit;
	tot = 1 << bit;
	for(int i = 0; i < tot; ++ i) {
		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << bit - 1);
	}
	
	memset(a, 0, tot * 8);
	memset(b, 0, tot * 8);
	
	for(int i = l; i <= mid; ++ i) a[i - l] = f[i];
	for(int i = 1; i <= r - l; ++ i) b[i - 1] = g[i];
	
	ntt(a, 1), ntt(b, 1);
	for(int i = 0; i < tot; ++ i) a[i] = (ll)a[i] * b[i] % P;
	ntt(a, -1);
	
	for(int i = mid + 1; i <= r; ++ i) {
		f[i] = (f[i] + a[i - l - 1]) % P;
	}
	solve(mid + 1, r);
}
C-挑选队友

题意:\(m\) 个群,\(n\) 位选手,选其中的k名,每个群中都应有至少一名,求方案数。

考虑生成函数 \(F_i(x) = \sum_{j = 1}^{s_i}\begin{pmatrix}s_i\\j\end{pmatrix}x^j\)

则答案即 \([x^k]\prod F_i(x)\)

实测分治时传 vector 的效率也不差。

submission

D-tokitsukaze and Another Protoss and Zerg

和上题基本一致,生成函数略有不同。

如果星族选 \(0\) 个,则虫族可选任意一个非空子集。

所以 \(F_i(x) =(2^{b_i} - 1) + \sum_{j = 1}^{a_i}\begin{pmatrix}a_i\\j\end{pmatrix}x^j\)

submission

牛顿迭代

推导

给定多项式 \(g(x)\),求满足 \(g(f(x)) = 0\) 的形式幂级数 \(f(x)\)

\(g(x) = b_0 + b_1x + \cdots b_kx^{k}, \ f(x) = a_0 + a_1x + \cdots\)

设当前求出 \(f\) 的前 \(n\) 项。

  • \(n = 1\) 时,解 \(g(a_0) = 0\)

  • 假设已经求出前 \(n\)\(f(x) \equiv a_0 + a_1x + \cdots a_{n - 1}x^{n - 1}\pmod {x^n}\)

    \(f(x) \equiv f_0(x) - \dfrac{g(f_0(x))}{g'(f_0(x))}\pmod{x^{2n}}\)

证明:

对于 \(g(f(x))\),有泰勒展开

\[\begin{aligned} g(f(x)) = g(f_0(x)) + g'(f_0(x))\cdot[f(x) - f_0(x)] + \dfrac{g''(f_0(x))}{2!}\cdot [f(x) - f_0(x)]^2 + \cdots \dfrac{g^{(n)}(f_0(x))}{n!}\cdot [f(x) - f_0(x)]^n + \cdots \end{aligned} \]

观察到 \(f(x) - f_0(x)\) 次数最小也有 \(x^n\)$。

所以在模 \(x^{2n}\) 意义下,从第三项开始都为 \(0\)

根据定义 \(g(f(x)) = 0\)

\(f(x) \equiv f_0(x) - \dfrac{g(f_0(x))}{g'(f_0(x))}\pmod{x^{2n}}\)

多项式求逆

\(h(x)\) 是给定的形式幂级数,求它的逆 \(f(x)\),则 \(g(f(x)) = \dfrac{1}{f(x)} - h(x)\)

得到的迭代式为(求导时 \(h(x)\) 可当做常数,\(f(x)\) 看成自变量

\[\begin{aligned} f(x) &\equiv f_0(x) - \dfrac{g(f_0(x))}{g'(f_0(x))}\\ \\ &\equiv f_0(x) - \dfrac{\dfrac{1}{f_0(x)} - h(x)}{-\dfrac{1}{f_0^2(x)}}\\ \\ &\equiv 2f_0(x) - f_0^2(x)\cdot h(x) \pmod {x^{2n}} \end{aligned} \]

边界 \([x^0]f(x) = [x^0]h^{-1}(x)\)

时间复杂度 \(O(\sum\limits_{i = 1}^{\log N} i \cdot 2^i) = O(N\log N)\)

介于本人不会求导,给出另一种推导方式。

已知 \(f_0(x) = f(x) \bmod {x^n}\)

\(f_1(x) = f(x) \bmod x^{2n}\)

\([f_1(x) - f_0(x)]^2 \equiv \pmod {x^{2n}}\)

\[f_1^2(x) - 2f_1(x)f_0(x) + f_0^2(x) \equiv 0 \pmod{x^{2n}} \]

在模 \(x^{2n}\) 意义下,\(f_1(x) * h(x) = 1\)

两边同乘 \(h(x)\)

\[f_1(x) - 2f_0(x) + f_0^2(x)h(x) \equiv 0 \pmod{x^{2n}} \]

P4238 【模板】多项式乘法逆

void polyinv(ll *f, const ll *h, int n){
	static ll d[N], g[N];
	int V = 1; while(V < n + n - 1) V <<= 1;
	memcpy(d, h, n * 8), memset(d + n, 0, (V - n) * 8);
	memset(f, 0, V * 8), memset(g, 0, V * 8);
	f[0] = qpow(h[0], P - 2);
	for(int w = 2; w / 2 < n; w <<= 1){
		memcpy(g, d, w * 8);
		for(int i = 0; i < w * 2; ++i) rev[i] = (rev[i >> 1] >> 1) | (i & 1 ? w : 0);
		ntt(f, w << 1, 1), ntt(g, w << 1, 1);
		for(int i = 0; i < w * 2; ++i) f[i] = (2 - f[i] * g[i]) % P * f[i] % P;
		ntt(f, w << 1, -1);
		memset(f + w, 0, w * 8);
	}
	memset(f + n, 0, (V - n) * 8);
}
  • \(n\) 为项数而不是次数。

  • \(w\)\(f_1(x)\) 的长度,当前已知长度为 \(w / 2\)\(f_0(x)\)

  • 由于要算 \(f_0^2(x) * h(x)\),所以 ntt 要开到 \(4\)\(w / 2\)

  • 做完 idft 后只需保留前 \(w\) 项,否则后续有影响。

多项式开方

\(h(x)\) 是给定的形式幂级数,求它的开方 \(f(x)\),则 \(g(f(x)) = f(x)^2 - h(x)\)

得到的迭代式为:

\[\begin{aligned} f(x) &= f_0(x) - \dfrac{f_0^2(x) - h(x)}{2f_0(x)} \pmod{x^{2n}}\\ \\ &= (f_0(x) + \dfrac{h(x)}{f_0(x)}) \cdot 2^{-1} \end{aligned} \]

P5205 【模板】多项式开根

void polysqrt(ll *f, const ll *h, int n){
	static ll d[N], g[N], f_inv[N];
	int V = 1; while(V < n + n - 1) V <<= 1;
	memcpy(d, h, n * 8), memset(d + n, 0, (V - n) * 8);
	memset(f, 0, V * 8), memset(g, 0, V * 8), memset(f_inv, 0, V * 8);
	f[0] = 1;
	constexpr int i2 = 499122177;
	for(int w = 2; w / 2 < n; w <<= 1){
		memcpy(g, d, w * 8);
		for(int i = 0; i < w * 2; ++i) rev[i] = (rev[i >> 1] >> 1) | (i & 1 ? w : 0);
		polyinv(f_inv, f, w);
		ntt(f, w << 1, 1), ntt(g, w << 1, 1), ntt(f_inv, w << 1, 1);
		for(int i = 0; i < w * 2; ++i) f[i] = (f[i] + f_inv[i] * g[i]) % P * i2 % P;
		ntt(f, w << 1, -1);
		memset(f + w, 0, w * 8);
	}
	memset(f + n, 0, (V - n) * 8);
}

例题

CF438E The Child and Binary Tree

题意:给定集合 \(\{c_1, c_2, \dots, c_n\}\quad(c_i \ge 1)\),有根二叉树的点权都属于该集合,左右儿子区分,问满足点权和 \(s = 1, 1, \dots,m\) 有多少不同二叉树。

\(f_n\) 表示点权和为 \(n\) 时的方案数。

\(v_i\) 表示 \(i\) 这个点权是否在集合中出现。

枚举左右子树的权值

\[f_n = \begin{cases} 1 & n = 0\\ \\ \sum\limits_{i = 1}^{n}v_i\sum\limits_{j = 0}^{v_i}f_{j}\cdot f_{v_i - j} &n > 0 \end{cases} \]

下式可写成卷积的形式:

\[f_n = \sum_{i + j + k = n}[v_i]\cdot f_j \cdot f_k \]

\(F(x) = \sum_{i \ge 1} f_0x^{i}\)

\(G(x) = \sum_{i \ge 1}[v_i]x^{i}\)

那么

\[F(x) = \sum[i > 0]\cdot [x^i][F^2(x)G(x)] + f_0 \]

由于题目保证了 \(c_i > 0\),所以 \([x^0]G(x) = 0\)

\(F = F^2G + 1\)

解方程:

\[F = \dfrac{1\pm \sqrt{1 - 4G}}{2G} \]

  • \(\lim\limits_{x\rightarrow 0}F(x) = f_0 = 1\)

  • \(\lim\limits_{x\rightarrow 0}G(x) = 0\)

取正号时,有 \(\lim\limits_{x\rightarrow 0}F(x) = +\infty\),舍去。

取负号时,有 \(\lim\limits_{x\rightarrow 0}F(x) = 1\),成立。

所以

\[F = \dfrac{1- \sqrt{1 - 4G}}{2G} \]

\([x^0]G(x) = 0\),无法求逆,考虑上下同乘 \(1 + \sqrt{1 - 4G}\)

\[F = \dfrac{2}{1 + \sqrt{1 - 4G}} \]

法2:牛顿迭代。

\(g(F(x)) = G(x)F^2(x) - F(x) + 1 = 0\)

  • \(F(x) \equiv 1 \pmod {x}\)

  • \(F(x) \equiv F_0(x)- \dfrac{G(x)F_0^2(x) + 1}{2G(x)F_0(x) - 1} \pmod {x^{2n}}\)

submission

F-卷积

题意:定义 \(F(x)=\sum_{i=1} f_ix^i\) ,其中 \(f_i=af_{i-1}+bf_{i-2}|(i>=2),f_0=0,f_1=1\)

给定 \(n, a, b\),求 \([x^{n}]\sum_{i\ge 1}F^i(x)\),(\(n \le 2\times 10^6\))。

\[\begin{aligned} F(x) &= f_1 + \sum_{i\ge2}(af_i - 1 + bf_{i - 2})x^i\\ \\ &= f_1 + axF(x) + bx^2(F(x) + f_0)\\ \\ &= 1 + axF(x) + bx^2F(x) \end{aligned} \]

\(F(x) = \dfrac{1}{1 - ax - bx^2}\)

\(\sum_{i\ge1}F^i(x) = \dfrac{F(x)}{1 - F(x)} = \dfrac{x}{1 -(a + 1)x - bx^2}\)

\(G(x) = \dfrac{1}{1 -(a + 1)x - bx^2}\),则答案转化为求 \([x^{n -1}]G(x)\)

到此步为止,已经可以 \(O(n\log n)\) 多项式求逆了。

复杂度依旧吃紧。

继续观察。

\(G(x)\)\(F(x)\) 比对,形式出奇一致。

得到 \(g_i = (a + 1)g_{i - 1} + bg_{i - 2}\),求 \(g_{n - 1}\)

可以 \(O(n)\) 计算,也可以 \(O(4\log N)\) 矩阵快速幂。

submission

reference

非's Blog

posted @ 2024-05-10 16:02  Lu_xZ  阅读(6)  评论(0编辑  收藏  举报