同余与逆元

同余

  • 前置知识 ————扩展欧几里得定理

  • 什么是同余

    对于两个数a,b,它们对于p取模结果相同,那么就称a和b在对p取模意义下同余
  • 公式表达

    <mstyle mathcolor="red"> a b ( m o d ) p </mstyle> \color{red}{a≡b(mod)p} ab(mod)p
  • 如何求一个数的同余

    利用扩展欧几里得定理
    我们将该公式转化一下 -> a % p = = b % p a\%p == b\%p a%p==b%p
    再变一下 -> a % p b % p = = 0 a\%p - b\%p == 0 a%pb%p==0
    再变一下 -> a % p + ( b % p ) = = 0 a\%p + (-b\%p) ==0 a%p+(b%p)==0
    诶,这个时候我们可以发现这个和扩欧的公式好像啊 ( a x + b y = = c ) (ax+by==c) (ax+by==c)
    那么是不是将其看成扩欧就可以解决了呢
    事实是————是的
    但是我们知道可以用扩欧求出一个同余来了,但是好像还是不知道怎么求,也不知道同余可以干什么啊
    事实上,在平常的写题中没有系数的同余都是很少出现的,一般同余是这么出现的-----
    a x b % p ax≡b\%p axb%p 它会告诉你一个系数再让你去求解
    更特殊的, b b b会等于1,这个时候,就扯到逆元上了

逆元

  • 什么是逆元

形如 a x 1 <mtext>   </mtext> m o d <mtext>   </mtext> p ax≡1\ mod\ p ax1 mod p x x x我们就称 x x x a a a m o d <mtext>   </mtext> p mod\ p mod p意义下的一个逆元,即 a a a乘以 x x x m o d <mtext>   </mtext> p mod\ p mod p的答案是1

  • 逆元有什么用

    在部分对一个很大的数字取模防止答案爆 l o n g l o n g long long longlong以至于表达不出来的题目中,有时会发现会用到除法,可是用整数除法会有问题啊,那怎么办呢又是那怎么办呢
    这个时候逆元就派上用场了
    我们发现, a x <mtext>   </mtext> m o d <mtext>   </mtext> p = = 1 ax\ mod\ p == 1 ax mod p==1 时,这个x等于 1 a \frac{1}{a} a1时就是一个最明显的满足条件的逆元,可是 1 a \frac{1}{a} a1不是一个整数啊,那怎么办呢?
    实际上,一个数对于另一个数取模时,它的逆元是有无数个的,只不过 1 a \frac{1}{a} a1是最小的一个,也就是说,还会有 a y m o d &ThinSpace;&ThinSpace; p = = 1 ay \mod p == 1 aymodp==1的存在,
    而这个时候,由于要对p取模,那么我们的a乘以x和乘以y的效果都是一样的,所以 1 a \frac{1}{a} a1可以被另一个常数y所代替,再想开一点,是不是所有的常数在对p取模时乘以 1 a \frac{1}{a} a1时都可以被y所代替呢, 由于p是不变的,所以这个结论是正确的

  • 如何求逆元

    • 求逆元有三种方式
      前面说过,有一种是可以用 e x _ g c d ex\_gcd ex_gcd来求的
      另外两种分别是费马小定理(有局限性,但是非常简单)和线性推逆元(线性的去求逆元,适用于大规模求逆元)
      • a x 1 m o d <mtext>   </mtext> b ax ≡ 1 mod\ b ax1mod b
      • a x % b = = 1 ax \% b == 1 ax%b==1
      • a x a x / b b = = 1 ax - ax/b*b == 1 axax/bb==1
      • y a x / b , a x + ( b ( y ) ) = = 1 设y为ax/b,ax + (b(-y)) == 1 yax/b,ax+(b(y))==1
      • y y 以下y为-y yy
      • a x + b y = = g c d ( a , b ) ax + by == gcd(a,b) ax+by==gcd(a,b)
      • 这个公式就可以套用扩欧了,下面再推一次扩欧
        g c d ( a , b ) = = g c d ( b , a % b ) = = g c d ( b , a a / b b ) gcd(a,b) == gcd(b,a\%b) == gcd(b,a-a/b*b) gcd(a,b)==gcd(b,a%b)==gcd(b,aa/bb)
        a x + b y = = g c d ( b , a a / b b ) = = b x + ( a a / b b ) y ax + by == gcd(b,a-a/b*b) == bx&#x27;+(a-a/b*b)y&#x27; ax+by==gcd(b,aa/bb)==bx+(aa/bb)y
        a x + b y = = b x + a y a / b y ax + by == bx&#x27; + ay&#x27; - a/b*y&#x27; ax+by==bx+aya/by
        a x + b y = = a y + b ( x a / b y ) ax + by == ay&#x27; + b(x&#x27;-a/b*y) ax+by==ay+b(xa/by)
        x = y , y = x a / b y x = y&#x27;,y = x&#x27; - a / b*y x=y,y=xa/by

    由此,我们可以得出求一个数的逆元的公式了
    e x _ g c d ( a , m o d , n i , x ) ex\_gcd(a,mod,ni,x) ex_gcd(a,mod,ni,x)// a a a为要求的数的逆元, m o d mod mod为模数, n i ni ni为逆元, x x x什么都不是
    n i = ( n i + m o d ) % m o d ni=(ni+mod)\%mod ni=(ni+mod)%mod;//防止负数


总结

  • 同余是当两个数都模一个p它们的余数相同,那么我们就称这两个数同余
  • 逆元是同余的一种常见特殊情况
  • 对于求逆元,首先要知道逆元有什么用:
  • 逆元是在取模运算中可以用乘法代替除法的巧妙工具

code:

void ex_gcd(int a,int b,int &x,int &y)
{
	if (b==0){x=1,y=0;return;}
	ex_gcd(b,a%b,x,y);
	int tmp=x;
	x=y,y=tmp-a/b*y;
}
全部评论

相关推荐

10-16 09:58
已编辑
门头沟学院 Java
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务