NOIP201208同余方程

题目描述 Description###

求关于x的同余方程(ax≡1(mod b)) 的最小正整数解。

输入描述 Input Description###

输入只有一行,包含两个正整数$ a,b$ ,用一个空格隔开。

输出描述 Output Description###

输出只有一行,包含一个正整数(x0) ,即最小正整数解。输入数据保证一定有解。

样例输入 Sample Input###

3 10

样例输出 Sample Output###

7

数据范围及提示 Data Size & Hint###

【数据范围】(2≤a,b≤2,000,000,000。)

之前的一些废话###

终于把辣鸡期中考试考完了

题解###

$ ax≡1(mod b)$ 可以等价于(ax-by=1) 该方程有解就说明(gcd(a,b)=1),所以(ax-by=gcd(a,b))就是用到了扩展欧几里得算法的做法,推法如下:
$ax-by=bx'-(a% b)y' ( ) =bx'-(a- {lfloor {a over b } floor} b)y' ( ) =-ay'+b(x'+ {lfloor {a over b } floor} y') $
$ Rightarrow x=-y' ( ) y=-x'-{lfloor {a over b } floor}y' $

之后就可以求了,注意最后求的解好像是负数,应该加成正数

代码###

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
#define mem(a,b) memset(a,b,sizeof(a))
typedef pair<int,int> PII;
#define X first
#define Y second
#define mp make_pair
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
int a,b;
PII exgcd(int a,int b)
{
	if(b==0){return mp(1,0);}
	PII tmp=exgcd(b,a%b);
	return mp(-tmp.Y,-tmp.X-(a/b)*tmp.Y);
}
int main()
{
	a=read();b=read();
	int ans=exgcd(a,b).X;
	while(ans<0)ans+=b;
	printf("%d
",ans);
	return 0;
}

总结###

没有

原文地址:https://www.cnblogs.com/FYH-SSGSS/p/7808294.html