数论/the second wave

扩展欧几里得算法。

void exgcd(int a,int b,int&x,int&y){
	if(!b) {
		x=1;y=0;return ;
	}
	exgcd(b,a%b,x,y);
	int temp=x;x=y;y=temp-a/b*y;
}

1)ax+by=c。 

   有解的条件是c%gcd(a,b)==0,因为ax+by=gcd(a,b)一定有解。

   设解是x0,y0,则通解 x=x0+(b/gcd(a,b))*t  y=y0-(a/gcd(a,b))*t 

2)ax ≡1 (mod m)

   x为a关于m的逆元,即ax-my=1,若gcd(a,m)!=1 无解

   设解是x0,则通解 x=x0+m*t 则a关于m的逆元是关于m同余的。则最小正整数解∈(0,m),那么x=(x0%abs(m)+abs(m))%abs(m);

noip2012同余方程:求出ax ≡1(mod n) 的最小正整数解。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define clr(x,c) memset(x,c,sizeof(x))
void exgcd(int a,int b,int&x,int&y){
	if(!b) {
		x=1;y=0;return ;
	}
	exgcd(b,a%b,x,y);
	int temp=x;x=y;y=temp-a/b*y;
}
int main(){
	int a,b,x,y;
	scanf("%d%d",&a,&b);
	exgcd(a,b,x,y);
	x=(x%b+b)%b;
	printf("%d\n",x);
	return 0;
} 

3)求ax≡t(mod b);

    可以求出ax+by=gcd(a,b)的解,若t%gcd(a,b)!=0无解。否则最小整数解x=(x0%abs(b/gcd)+abs(b/gcd))%abs(b/gcd)*(c/gcd)

 

eg

int cal(int a,int b,int c){
	int x,y;
	int gcd=exgcd(a,b,x,y);
	x*=c/gcd;
	b/=gcd;
	if(b<0) b=-b;
	return (x%b+b)%b;
}

  

posted @ 2016-07-31 21:44  BBChq  阅读(158)  评论(0编辑  收藏  举报