• 逆元板子集


    其实就是怕忘了……这里发一下线性求逆元以及阶乘的逆元的板子。

    线性求逆元

    逆元是啥我就不说了,但是线性递推式怎么来的我还是可以证明一下的。

    求 i 的逆元,假设[1, i - 1]的逆元已知。

    设 p = k * i + b,则 b = p % i, k = ⌊p / i⌋ 。

    则k * i + b Ξ 0 (mod p),所以b Ξ - k * i。

    两边同乘inv[b]得:inv[b] * b Ξ - k * i * inv[b] (mod p)

    化简得:    - k * i * inv[b] Ξ 1 (mod p)

    两边同乘inv[i]得:inv[i] Ξ - k *inv[b] (mod p)

            inv[i] Ξ (p - k) * inv[b]

            inv[i] Ξ (p - ⌊p / i⌋) * inv[p % i]

    所以      inv[i] = (p - ⌊p / i⌋) * inv[p %i] % p

    装模作样来个代码。

    1 inv[1] = 1;
    2 for(int i = 2; i <= n; ++i) inv[i] = inv[mod % i] * (mod - mod / i) % mod;

    线性求阶乘的逆元

    其实就是根据inv[i] = inv[i + 1] * (i + 1) % p倒着递推而来。

    先用费马小定理求出inv[n]的逆元,然后倒着递推。

     1 ll quickpow(ll a, ll b)
     2 {
     3     a %= mod;
     4     ll ret = 1;
     5     for(; b; b >>= 1, a = a * a % mod) 
     6         if(b & 1) ret = ret * a % mod;
     7     return ret;
     8 }
     9 ll fac[maxn], inv[maxn];
    10 void init(int n)
    11 {
    12     fac[1] = 1;
    13     for(int i = 2; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;
    14     inv[n] = quickpow(fac[n], mod - 2);
    15     for(int i = n - 1; i; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
    16 }
  • 相关阅读:
    Java监听器Listener使用详解
    浮点数运算
    变量
    java For 循环 运行顺序
    java ++运算
    一些硬件厂商的MAC号
    c# 双问号运算
    SQL Server 触发器
    微软企业库Microsoft Enterprise Library的相关文章链接
    关于ligerUi的ligertree的初始化默认选中指定项目的方法
  • 原文地址:https://www.cnblogs.com/mrclr/p/9833765.html
Copyright © 2020-2023  润新知