基础数论(3)同余、逆元 |
您所在的位置:网站首页 › 如何求余 › 基础数论(3)同余、逆元 |
同余和逆元
本篇博客将介绍同余和逆元,以及求逆元的三种方法(因为快速幂是本菜鸡在很久之前c语言还没学完的时候扣了一晚上看懂了,所以默认大家都会了) 放到一起总结一下。拖了好久的说。。。 然后,开始了。。。 同余 定义给定一个正整数m,如果两个整数a和b满足a-b能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作a≡b(mod m)。对模m同余是整数的一个等价关系。(百度百科) 换句话说,就是两个整数a和b对于m取模时的余数相等,称a和b对于模m同余。记作a≡b(mod m)。 举个栗子吧,比如: 6 | (47-35)成立, 因此47≡35(mod 6),分析一下就是47%6=5,35%6=5,满足余数相等,因此说47和35对模6同余。 然后放一些与同余有关的定理吧 下面说一个很有用的东西,也为了给后面的逆元做铺垫吧。这个很简单,大佬们可以直接跳过。 性质
然后迫不及待的小伙伴们可能发现了,上面的两条性质包括了加减和乘法,遇到除法我们该怎么进行随时取模的运算呢? 然后就引出了我们此篇博客的重点,逆元。 逆元 定义它是一个可以取消另一给定元素运算的元素。 对于正整数a和m,如果有a*x≡1(mod m),那么把这个同余方程中x的最小正整数解叫做a模m的逆元。 思考了许久,先给一个前提吧,当然通用方法也会在后面附上。 前提求a(modm)意义下的逆元,要求a与m互质,否则不存在乘法逆元 简单理解来说,就是化除法为乘法,举个栗子,当我们遇到a/b的时候,我们可以将其变为a*(1/b),也就是取倒数。只不过是在取模意义下的取倒数操作。 说起来很简单,但是实践起来还是一脸懵逼,本篇总结一下网上流传的三种常用方法吧。 (一)费马小定理求逆元首先引入费马小定理: 然后我们就可以利用这一定理求逆元了,很容易看出来 a(p-1) ≡ 1(mod p)可以变为a*a(p-2)≡ 1 (mod p) 此时a在模p意义下的逆元就很显然的能看出来了,是a(p-2),然后这个逆元我们就可以通过快速幂来求得,这是很简单很常用的一种方法。 代码(其实就是一个快速幂啦) #include typedef long long ll; using namespace std; ll quickmi(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1)ans=(ans*a)%p; a=(a*a)%p; b=b/2; } return ans; } int main() { ll p,a; cin>>a>>p; ll inv=quickmi(a,p-2,p); cout x=1,y=0; return ; } exgcd(b,a%b,x,y); ll t=y; y=x-(a/b)*y,x=t; return ; } int main() { ll p,a,x,y; cin>>a>>p; exgcd(a,p,x,y); cout ll ans=1; while(b) { if(b%2==1)ans=(ans*a)%p; a=(a*a)%p; b/=2; } return ans; } void init(ll p,int n) { fac[1]=1; for(int i=2;i=1;i--) { inv[i]=inv[i+1]*(i+1)%p; } return ; } int main() { ll mod,n; cin>>mod>>n; init(mod,n); for(int i=1;i |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |