利用扩展欧几里得求一元同余方程和求逆元

先明白扩展欧几里得求不定方程:https://blog.csdn.net/A_Pathfinder/article/details/88131225

再放个逆元整理的:https://blog.csdn.net/weixin_41162823/article/details/82824988?tdsourcetag=s_pctim_aiomsg

同余的定义:给出一个正整数m和两个整数a,b,如果( (a-b)%m )==0,则称a和b模m同余,反之记作a和b不同余m;
                     例如 -7
-1159(mod 4);记作ab(mod m);

定理1:对于( (a-b)%m )==0,当且仅当存在整数k,a=b+k*m;

        2:在一个同余式两边同时做加法,减法或者乘法,依然保持同余。(没有除法

        3:对于正整数m和整数a,b,c,d=gcd(c,m),并且ac≡bc(mod m)。则ab(mod(m / d) )。例:m=4,a=3,b=1,c=6,gcd(c,m)=gcd(6,4) = 2;并且6*36*1(mod 4)。则31(mod 2)。(用这个求同余方程)

再给出一些运算规则:

(a + b)%p=(a%p+b%p)%p;    (a-b)%p=(a%p-b%p)%p;   (a*b)%p=(a%p*b%p)%p;    (a^b)%p= ( (a%p)^b )%p;

( (a+b)%p + c )%p = (a+(b+c)%p)%p;    ( (a*b)%p*c )%p = (a*(b*c)%p)%p;  (结合律)

(a+b) %p =(b+a)%p;       (a*b)%p=(b*a)%p     (交换律)

( (a+b)%p *c)%p = ( (a*c)%p + (b*c)%p )%p (分配律)

练习题:poj 1995

下面是求同余方程:


定义:形如ax≡b(mod m)是同余方程。

定理:gcd(a,m)=d。如果 b mod d !=0;则方程无解,否则恰好有d个模m不同余的解。

          注:这里其实可以看作是 ax=b+ym, ax-ym=b,就可以换成exgcd求不定方程了,没看着的那么恶心,然后用exgcd求不定方程的解的定理b%gcd(a,m)来判断解的个数,要注意的是x= x0+k*(b / gcd(a,m) )  ; y= y0+k*(a / gcd(a,m) ); 因为是ax-ym的解。

定理2(求逆元):gcd(a,m)=1,称ax≡1(mod m)的一个整数解为a模m的逆;

                              注:也就是若a*x≡1(mod m),a*x-m*y=1 ,a,m互质(所有解都模m同余),则称x为a关于m的逆元,逆类似与倒数的概念类似。

 除法模运算:设c为b在对P取模状态下的逆元,在求(a/b)%P时,很可能会因为b过大而超过精度范围,这时候可以将除法转换成乘法来做,(a/b)%P = (a*Invb)%P =( (a%P)*(Invb%P)%)P

例:假设x是a的逆元,a^-1≡x(mod m)等价与ax≡1(mod m);x等价与a^-1,可以带3 ,11,得出x为4,4就是满足于3关于11的逆元。

模板代码:

#include
using namespace std;
int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1;y=0;
		return a;
	}
	int t=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return t;
}
int get_inv(int a,int m){ //a*x=1(mod m) b是1
	int d,x,y;
	d= exgcd(a,m,x,y);
	if(d==1)//a,b互素
	return (x%m+m)%m;
	else
	return -1; 
	
}
int main(){
	int a,b,m;//对于求a的逆元,只要保证ax-my=b,b=1&&gcd(a,m)=1 
	cin>>a>>m; //b不等于1就是普通的解不定方程 
	//cout<

例题:ZOJ 3609

 

 

 

 

 

 

 

 

你可能感兴趣的:(模板,数论)