同余式

同余式

1. 算法分析

1.1 同余式常用定理

1.1.1 欧拉公式/费马小定理

欧拉公式:
    若gcd(a, n) = 1, 则aφ(n) = 1 (mod n)
费马小定理
    若p是质数,则ap = a(mod p) => ap-1 = 1(mod p)
欧拉公式/费马小定理常用来化简式子,通过aφ(n) = 1 (mod n)的关系,把式子的一部分转换为1

1.1.2 威尔逊公式
  1. p为素数 <=> (p - 1)! ≡ -1(mod p)
  2. p为素数 <=> (p - 1)! ≡ (p - 1) (mod p)
  3. p为素数 <=> p | ((p-1)! + 1)

因此,当发现算式有 (p-1)! 时,可以考虑威尔逊定理的使用

1.1.3 扩展欧几里得

对于方程:

ax+by = m
方程有解 <=> gcd(a, b) | m

特殊地,ax+by=1有解 <=> gcd(a, b)=1
输入a,b,使用扩展欧几里得算法可以求出ax + by = gcd(a, b)的一个解为(x0, y0),那么ax + by = gcd(a, b)的通解为:

\begin{cases}
x = x0+(b/gcd)*t \\
y = y0-(a/gcd)*t 
\end{cases}

ax + by=m的通解为:

\begin{cases}
x = x0*m/gcd+(b/gcd)*t \\
y = y0*m/gcd-(a/gcd)*t \\
(这里的x0、y0是ax+by=gcd求出来的)
\end{cases}

ax+by=gcd(a, b)和ax+by=m的通解的周期都是b/gcd,不会变

对ax+by=m进行变形,ax ≡ m (mod b)
则x∈[0, b),解的数目为gcd(a, b)个,第一个解在[0, b/gcd),第二个解在[b/gcd, 2b/gcd),…

1.2 乘法逆元

  1. 扩展欧几里得
    ax ≡ 1(mod p) <=> ax + py ≡ 1(mod p),因此可以使用扩展欧几里得求ax + py ≡ 1(mod p)解逆元,求出来的逆元就是x

  2. 费马小定理
    ap-1 ≡ 1(mod p) <=> a的逆元为ap-2(mod p),当且仅当p为素数情况

  3. 线性求逆元
    首先有
    1-1≡1(mod p)

    p=k * i + r, r < i, 1 < i < p
    两边同时mod p,有
    k * i + r ≡0 (mod p)
    两边同时乘上i-1 * r-1,得到
    k* r-1+ i-1≡ 0(mod p)
    移项
    i-1≡-k * r-1 (mod p)
    i-1≡-⌊P/i⌋ * (p mod i)-1 (mod p)
    以inv(i)表示i在mod p下的逆元,则有递推公式:
    inv[i]= -(p/i) * inv[p % i]

1.3 求解同余式

1.3.1 求解一次同余式

求解一次同余式 ax ≡ 1(mod p), 直接乘法逆元求解

1.3.2 求解高次同余式

求解高次同余式 ax ≡ 1(mod p), 使用baby Step,Giant Step算法求解

1.4 中国剩余定理

  1. 原始版中国剩余定理

假设整数m1,m2, … ,mn两两互质,则对任意的整数:a1,a2, … ,an,方程组 (S) 有解,并且通解可以用如下方式构造得到:

\begin{cases}
x ≡ a1 (mod m1) \\
x ≡ a2 (mod m2) \\ 
x ≡ a3 (mod m3) \\
x ≡ a4 (mod m4)
\end{cases}

有解的判定条件,并用构造法给出了在有解情况下解的具体形式。
中国剩余定理说明:假设整数m1,m2, … ,mn两两互质,则对任意的整数:a1,a2, … ,an,方程组 有解,并且通解可以用如下方式构造得到:
x = ∑ i = 1 n   a i ∗ t i ∗ M i + k M x = \sum_{i=1}^n\ {ai * ti * Mi} + kM x=i=1n aitiMi+kM
在mod M的意义下:
x = ( ∑ i = 1 n   a i ∗ t i ∗ M i ) m o d M x = (\sum_{i=1}^n\ {ai * ti * Mi} ) mod M x=(i=1n aitiMi)modM

  1. 拓展版中国剩余定理

普通的中国剩余定理要求所有的mi互素, 那么如果不互素呢,求解同余方程组方法如下:
①这种情况采用两两合并的思想,假设要合并如下两个方程:
x = a1 + m1x2
x = a2 + m2x2
那么得到: a1+ m1x1 = a2 + m2x2 => m1x1 + m2x2 = a2 - a1

②使用扩展欧几里得算法得到一个最小的x1,从而得出最小的x使他满足:
x = a1 + m1x1 = a2 + m2x2
这样得到的是x的一个特解x’,当然也是最小正整数解

③所以x的通解一定是x’加上lcm(m1,m2)*k,这样才能保证x模m1和m2的余数是a1和a2.由此,我们把这个x’当作新方程的余数,把lcm(m1, m2)当作新的方程的模数
合并完成:x ≡ x’ (mod lcm(m1, m2))

1.5 思维同余性质

  • 同余的考题很多结合距离可以回头的概念,比如自西向东一旦到了尽头那么又是自西向东,这样会产生同余的情况
  • 还有很多考察欧拉公式等

2.板子

2.1 同余式常用定理

扩展欧几里得算法

// 扩展欧几里得算法:ax+by=gcd(a, b),返回值为d=gcd(a, b)
int exgcd(int a, int b, int &x, int &y) {
   
    if (!b) {
      // b==0时,x=1, y=0
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, y, x); // b != 0时,gcd(a, b) = gcd(b, a % b), x = x, y = y - a/b * x;
    y -= a / b * x;
    return d;
}

2.2 乘法逆元

  1. 扩展欧几里得求逆元
// 扩展欧几里得算法:ax+by=gcd(a, b),返回值为d=gcd(a, b)
LL exgcd(LL a, LL b, LL &x, LL &y) {
   
    if (!b) {
     // b==0时,x=1, y=0
        x = 1, y = 0;
        return a;
    }
    LL d = exgcd(b, a % b, y, x); // b != 0时,gcd(a, b) = gcd(b, a % b), x = x, y = y - a/b * x;
    y -= a / b * x;
    return d;
}

LL getInv(LL a, LL mod) {
     //求a在mod下的逆元,不存在逆元返回-1
    LL x, y;
    LL d = exgcd(a, mod, x, y);
    return d == 1 ? (x % mod + mod) % mod: -1;
}
  1. 费马小定理求逆元
LL qmi(LL a, LL k, LL p)   {
   
    LL res = 1 % p;  // res记录答案, 模上p是为了防止k为0,p为1的特殊情况
    while(k) {
    // 只要还有剩下位数
        if (k & 1) res = (LL)res * a % p;  // 判断最后一位是否为1,如果为1就乘上a,模上p, 乘
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值