首页 > 代码库 > 数论小结2.

数论小结2.

---恢复内容开始---

今天江哥来个给我们讲一些数学方面的小知识...小小总结一下!

 

1. exgcd().

  

技术分享
1 inline ll exgcd(ll a,ll b,ll c){2     return c % a ? (exgcd(b % a, a, ((-c % a) + a) % a) * b + c) / a : c / a;3 }
View Code

江哥的神代码... 非常简单直接就能求逆元.

 

2.线筛 prime && phi && 逆元

技术分享
 1 inline void sieve(){ 2     for(ll i = 2; i < maxn; ++i) 3         if(!vis[i]){ 4             prime[++sz] = i; 5             for(ll j = i*i; j < maxn; j += i) vis[j] = 1; 6         } 7 } 8  9 10 inline void get_phi(){11     phi[1] = 1;12     for(int i = 2; i < maxn ; ++i){13         if(!vis[i]){ prime[++sz] = i; phi[i] = i-1; }14         for(int j = 1; j <= sz && prime[j] * i < maxn; ++j){15             vis[prime[j] * i] = 1;16             phi[prime[j] * i] = phi[i] * (i % prime[j] ? prime[j] - 1 : prime[j]);17         }18     }    19 }
View Code

某些情况下必须快速筛phi吧.

因为 phi 函数是一个积性函数, 我们从 phi 函数的计算式来考虑, 对于一个数, N = a * p, 如果 a % p == 0 那么 phi(N) = phi(a) * p, 否则 phi(N) = phi(a)  * (p - 1).

然后线筛逆元的想法是 , inv(n!) = inv((n-1)!) * n... 然后我们就能够线性递推...进而推出 1~n 的逆元.

 

3. CRT

CRT 是求一个同余方程组的解 x ≡ b(mod pi) ... 以前一直是写的暴力的 CRT(暴力做加法....).

但是我们如果这样想..... x = a1 + a2 + a3, 其中只有 ai 对方程 i 有贡献 (ai % pj != i)== 0

这个问题就好办了, 用 exgcd 求出每个ai, 然后求和就能得到一个 x 的解.

 

4. Lucas && ex_Lucas.

Lucas: C(n,m) % p == C(n % p, m % p) * Lucas(n / p, m / p);

ex_Lucas: 主要思想是将 C(n,m) 中的 模数 p 的因子提出来, 然后再求逆元...(p 不能太大)

 

5. Bs_Gs()

  求离散对数 ax ≡ b (mod p).

  hash x = [1, √p], 然后 b 每次乘上 inv(a√p ), 再去 hash 表中找.

  Bs_Gs() 能够拓展.

6. 离散开方

  x≡ b (mod p).

  我们在这里使用原根 g 来表示 x 以及 b.(原根的定义自行 Wiki)

  先计算出 p 的原根 g 然后用Bs_Gs()计算指数.

  x≡ b (mod p) => (gi)≡  g(mod p).根据费马小定理 ap - 1 ≡ 1 (mod p).

  => i * a ≡ j (mod p - 1).
    求解线性模方程用 exgcd 就 ok 了.

7. FFT

  大体思路:

    利用多项式的点值表示来计算乘积,运用分治的思想进行快速插值与逆差值.

  待补全....

数论小结2.