在 ACM 竞赛中,由于 C++ 库中没有大数类,手写大数类有些麻烦且写好类接口再应用仍然很麻烦,因此我们经常在有限域 $\mathbb{Z} / p \mathbb{Z}$ 中考虑问题。这里介绍一下 Lucas 定理,及在一类递推关系式中的应用。
Lucas定理
对任意非负整数 $m,n$ 和素数 $p$,我们有:
$$ C_{m} ^ n = \prod_{i=0} ^k C_{m_i} ^{n_i} \mod p$$
其中 $m = \sum_{i=0} ^k m_i p^i,n = \sum_{i=0} ^k n_i p^i$。
Proof: 由组合数的定义
$$ C_{p} ^ n = \frac{p(p-1) \cdots (p-n+1)}{n(n-1) \cdots 1} $$
容易看出 $p \mid n! \, C_{p} ^ n $, 因此当 $n<p$ 时,$p \mid C_{n} ^ p $。即我们有
$$ (1+x)^p = 1 + x^p \mod p$$
因此
$$ \begin{align}
\sum_{n=0}^m C_{m}^n x^n &= (1+x)^m = \prod_{i=0} ^k \left( (1+x)^{p^i} \right)^{m_i} \\
&= \prod_{i=0}^k \left( 1+x^{p^i} \right)^{m_i} = \prod_{i=0}^k \left( \sum_{n_i=0}^{m_i} C_{n_i}^{m_i} x^{n_ip^i} \right) \\
&= \sum_{n=0}^m \left(\prod_{i=0} ^k C_{m_i} ^{n_i} \right) x^n \mod p
\end{align} $$
由多项式对应系数相等,证毕。
一类递推关系决定的数列
已知 $f(n) = (a+\sqrt{b})^n + (a-\sqrt{b})^n$ 则容易知道其可由 $f(0)=2,f(1)=2a$, $f(n)=2af(n-1)+(b-a^2)f(n-2)$ 相互决定。现在我们要计算 $f(n) \mod p$,其中 $p$ 是素数,如果 $b$ 是 $p$ 的二次剩余,就可以直接计算,并且可以看出此时 $f(n)$ 的周期是 $p-1$。否则,我们用矩阵的策略来计算,这个已经是套路了,可看我之前的博文。
令 $ A = \left[ \begin{matrix} 2a & b-a^2 \\ 1 & 0 \end{matrix} \right] $ 则
$$ \left( \begin{matrix} f(n+1) \\ f(n) \end{matrix} \right) = A \left( \begin{matrix} f(n) \\ f(n-1) \end{matrix} \right) = A^n \left( \begin{matrix} 2a \\ 2 \end{matrix} \right) $$
即我们只需计算 $A^n$ 即可。并且我们知道 可逆矩阵 $A^n$ 的周期是 $(p^2-1)(p^2-p)$。问题在于若 $p=1e9+7$ 这个周期要用 $__int128$ 来存储(其实这也是可以的,但是如果 $p=1e18+9$ 呢)。对于刚过所说的这种特殊情况。其实此时 $A$ 的周期(不一定是最小)为 $p^2-1$。实际上我们只要说明 $f(n)$ 的周期是 $p^2-1$ 即可。但对于一般的 $A$ 并不清楚。
因为 $f(p^2)$ 展开后不含 $\sqrt{b}$ 项,且由 Lucas 定理知道,$C_{p^2}^i,0 \leq i \leq p^2$ 中,非0数仅有 $C_{p^2}^0 = C_{p^2}^{p^2} = 1 \mod p$。因此 $f(p^2) = 2a^{p^2} = 2a \mod p$。
类似地,$C_{p^2+1}^i,0 \leq i \leq p^2+1$ 中,非0数仅有 $C_{p^2+1}^0,C_{p^2+1}^1,C_{p^2+1}^{p^2},C_{p^2+1}^{p^2+1} \mod p$。因此:
$$ f(p^2+1) = 2(a^{p^2+1} + (\sqrt{b})^{p^2+1})= 2(a^2+b) = f(2)$$
由$f(n)$的取值由前两项(相邻两项,后两项)唯一确定,因此$f(n+p^2-1) = f(n),n>=0$。
上面这一段证明来自 Bestcoder 81。更简单的证明见这里
注意事项
这类问题精彩需要注意的是:
- 矩阵中元素本身是p的倍数时很容易出问题。
- 不要溢出,不要出现负数
HDU 5674
1 | //#pragma comment(linker,"/STACK:10240000,10240000") |