扩展欧几里德与中国剩余定理学习笔记&&模版

蒟蒻这几天比较闲,于是自学了早就学了很久的扩欧与中国剩余定理。。。。。。

--------------------------------------------------------------------------------------------------------------扩展欧几里德-------------------------------------------------------------------------------------------------------         扩展欧几里德算法(用于求解px+qy=gcd(p,q)类问题):

        px+qy=gcd(p,q)  记n=gcd(p,q) 则:

        y=(n-px)/q=[n-(p mod q)x]/q-[p/q]x   (p mod q=p-[p/q])

        记y0=x   x0=[n-(p mod q)x]/q=[n-(p mod q)y0]/q

        其等价于 qx0+(p mod q)y0=n-(p mod q)y0+(p mod q)y0=n

        递归求解即可; code(求ax+by=gcd(a,b)的一组可行解):  

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a,b,x,y;
void exgcd(int a,int b)
{
	int t;
	if (a%b==0)
	  {
	    x=0; y=1;
	  }
	else
	  {
	    exgcd(b,a%b);
	    t=x; x=y; y=t-(a/b)*y;
	  }
}
int main()
{
	scanf("%d%d",&a,&b);
	exgcd(a,b);  
	printf("%d %d\n",x,y);
}

       若要求解最小正整数,分别将x,y对lcm(a,b)取模  (lcm(a,b)*gcd(a,b)=a*b)

       那么,我们既可以解决类似于  ax=c (mod b) 的同余方程最小解(满足 c|gcd(a,b))

       我们可以将ax=c (mod b) 转化为 ax+by=c 的最小解,那么我们可以求出  ax+by=gcd(a,b)  再将 x 乘上 c/gcd(a,b) 即可(最后模去b)

       code:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a,b,c,x,y,gcd;
void exgcd(int a,int b)
{
	int t;
	if (a%b==0)
	  {
	    x=0; y=1;
	    gcd=b;
	  }
	else
	  {
	    exgcd(b,a%b);
	    t=x; x=y; y=t-(a/b)*y;
	  }
}
int main()
{
	scanf("%d%d%d",&a,&b,&c);
	exgcd(a,b); 
	x=(x%b+b)%b;
	x=x*(c/gcd);
	x%=b; 
	printf("%d\n",x);
}
 那么我们就解决了线性同余方程,那么问题来了,线性同余方程组怎么办?

-------------------------------------------------------------------------------------------------------中国剩余定理--------------------------------------------------------------------------------------------------------------

远离不再赘述,我在此只给出总式

        已知 x=b1(mod m1)  x=b2(mod m2)......x=bi(mod mi)......x=bn(mod mn) N=m1+m2+m3+........+mn

              则x=

                 

                 exgcd(a,b)返回以上程序的x

      code:         

#include<cstdio>
using namespace std;
int b[100],m[100];
int n,x,y,N;
void exgcd(int a,int b)
{
	int t;
	if (a%b==0)
	  {
	    x=0;
	    y=1;
	  }
	else
	  {
	    exgcd(b,a%b);
	    t=x;
	    x=y;
	    y=t-(a/b)*y;
	  }
}
int main()
{
	int i,now,ans;
	scanf("%d",&n); N=1; ans=0;
	for (i=1;i<=n;++i)
	  {
	    scanf("%d%d",&b[i],&m[i]);
	    N=N*m[i];
	  }
	for (i=1;i<=n;++i)
	  {
	    now=N/m[i];
	    now=now%m[i];
	    exgcd(now,m[i]); 
	    x=(x%m[i]+m[i])%m[i];
	    x=(x*(N/m[i])*b[i])%N; 
	    ans=(ans+x)%N;  
	  }
	printf("%d\n",ans);
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                                                                                                                                                                                                                                                                                         Lcomyn

你可能感兴趣的:(扩展欧几里德与中国剩余定理学习笔记&&模版)