数论版块——扩展 BSGS 与扩展 Lucas 定理 模板总结

BSGS & exBSGS

Description

给定 a , b , p a,b,p a,b,p,你需要找到最小的满足 a x ≡ b ( m o d p ) a^x \equiv b \pmod p axb(modp) x x x

T T T 组数据, ∑ p ≤ 5 × 1 0 6 \sum \sqrt p \le 5 \times 10^6 p 5×106

算法一(BSGS: 保证 gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1)

B = ⌈ p ⌉ B=\lceil \sqrt p \rceil B=p t = a B t=a^B t=aB

我们先将 a 0 , a 1 , ⋯   , a B a^0,a^1,\cdots,a^B a0,a1,,aB 分别压入哈希表中,接着枚举 i = 0 , 1 , ⋯ i=0,1,\cdots i=0,1,,同时算出 b t i \frac {b} {t^{i}} tib 在模意义下的值。如果该值在哈希表中出现过,则我们就得到了答案。

时间复杂度 O ( B ) O(\sqrt B) O(B )。逆元可以用扩展欧几里得算法求解(在 p p p 为质数的时候也可以用费马小定理),哈希表可以使用 unordered_map 来实现。

算法二(exBSGS)

若不保证 gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1,那么就无法算出 b t i \frac {b} {t^i} tib 在模意义下的值了,因为 t i t^i ti 在模意义下可能不存在逆元。所以我们考虑将其转化为 gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1 的情况,这样就能直接套用算法一了。

考虑计算出 d = gcd ⁡ ( a , p ) d=\gcd(a,p) d=gcd(a,p),那么问题就转化为求出最小的 x x x 使得 ( a d ) a x − 1 ≡ b p ( m o d p d ) (\frac a d)a^{x-1} \equiv \frac b p\pmod {\frac {p} d} (da)ax1pb(moddp)。注意到 a d \frac a d da p d \frac p d dp 是互质的,所以我们可以计算出 a d \frac a d da 的逆元并将其提到右边,这样就转化为了一个本质相同而规模减小的子问题 a x − 1 ≡ b d × a d − 1 ( m o d p d ) a^{x-1} \equiv {\frac b d}\times {\frac a d}^{-1} \pmod {\frac p d} ax1db×da1(moddp),可以递归解决。

特别的,当 d = 1 d=1 d=1 时,我们直接调用 BSGS 就行了。此外,注意特判 b = 1 b=1 b=1 p = 1 p=1 p=1 的情况,此时应直接返回 0 0 0。同时,要注意假设目前已经递归到了第 k k k 层(刚开始是第 0 0 0 层),那么真正的答案应该还要再加上 k k k

注意到每次 p p p 都至少除以 2 2 2,所以 p p p 至多会变化 log ⁡ p \log p logp 次,而每次都要通过辗转相除计算一次 gcd,所以总复杂度是 O ( log ⁡ 2 p + p ) O(\log^2 p+\sqrt p) O(log2p+p ) 的。

由于 unordered_map 的巨大常数,洛谷上会轻微卡常。

Lucas & exLucas

Description

给定 n , m , p n,m,p n,m,p,求 ( n m )  mod  p {n \choose m} \ \text{mod} \ p (mn) mod p

1 ≤ n , m ≤ 1 0 18 , 1 ≤ p ≤ 1 0 6 1 \le n,m \le 10^{18},1 \le p \le 10^6 1n,m1018,1p106

算法一(Lucas: 保证 p p p 为质数)

首先,如果 n , m < p n,m<p n,m<p,那么可以直接阶乘逆元求解。那么 n , m ≥ p n,m \ge p n,mp 的话该怎么办呢?

Lucas 定理给出

( n m ) ≡ ( ⌊ n p ⌋ ⌊ m p ⌋ ) × ( n  mod  p m  mod  p ) ( m o d p ) {n \choose m} \equiv {{\lfloor \frac n p \rfloor} \choose {\lfloor \frac m p \rfloor}} \times {{n \ \text{mod} \ p} \choose m \ \text{mod} \ p} \pmod p (mn)(pmpn)×(m mod pn mod p)(modp)

递归求解即可。

时间复杂度 O ( p + log ⁡ p n ) O(p+\log_p n) O(p+logpn)

算法二(exLucas: 不保证 p p p 为质数)

首先考虑对 p p p 进行质因数分解,将其拆分为 p = ∏ i = 1 k a i b i p=\prod_{i=1}^k a_i^{b_i} p=i=1kaibi 的形式( ∀ i ∈ [ 1 , p ] \forall i \in [1,p] i[1,p] a i a_i ai 为质数),那么只要我们对于每个 i i i 求出了 ( n m ) {n \choose m} (mn) a i b i a_i^{b_i} aibi 取模后的值,通过 CRT 合并就能得到答案了。所以关键在于,当模数为某个质数的若干次方 p q p^q pq 的时候,如何算出组合数 ( n m ) {n \choose m} (mn) 在模意义下的值。

考虑计算出 n ! , m ! , ( n − m ) ! n!,m!,(n-m)! n!,m!,(nm)! 中分别包含多少个质因子 p p p。假设分别有 x , y , z x,y,z x,y,z 个,那么 ( n m ) {n \choose m} (mn) 中就包含了 x − y − z x-y-z xyz 个质因子 p p p。那么,如果 x − y − z ≥ q x-y-z \ge q xyzq,那么显然 ( n m ) ≡ 0 ( m o d p q ) {n \choose m} \equiv 0 \pmod {p^q} (mn)0(modpq)。否则,我们考虑分别求出 n ! , m ! , ( n − m ) ! n!,m!,(n-m)! n!,m!,(nm)! 去掉所有质因子 p p p 后的值 u , v , w u,v,w u,v,w,那么答案即为 u ! v ! w ! \frac {u!} {v!w!} v!w!u! p q − ( x − y − z ) p^{q-(x-y-z)} pq(xyz) 再乘上 p x − y − z p^{x-y-z} pxyz 的值,显然可以通过扩展欧几里得算法求出。

所以关键在于,如何求出把 n ! n! n! 中的所有质因子 p p p 去掉后的值 f ( n , p ) f(n,p) f(n,p)。不难发现, f ( n , p ) f(n,p) f(n,p) 的组成分为三个部分,其中第一个部分是 [ 1 , n ] [1,n] [1,n] p p p 的倍数,第二个部分是 [ 1 , p × ⌊ n p ⌋ ] [1,p \times \lfloor \frac {n} {p} \rfloor] [1,p×pn] 中非 p p p 的倍数,第三个部分就是 ( p × ⌊ n p ⌋ , n ] (p \times \lfloor \frac {n} {p} \rfloor,n] (p×pn,n] 中的所有数。对于第一个部分,我们可以递归求解;对于第二个部分,不难发现其乘积由若干个连续段组成,而根据威尔逊定理,其中任何一个连续段的乘积均为 − 1 -1 1,所以这一部分的贡献就是 ( − 1 ) ⌊ n p ⌋ (-1)^{\lfloor \frac n p \rfloor} (1)pn;而对于第三个部分,注意到其乘积在模意义下与 ( n  mod  p ) ! (n \ \text{mod} \ p)! (n mod p)! 相等,通过预处理出各个数在模意义下的的阶乘,每次就可以 O ( 1 ) O(1) O(1) 调用了。

总时间复杂度与 O ( p log ⁡ p ) O(p \log p) O(plogp) 同级。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值