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 } \rfloor} b)y' \( \) =-ay'+b(x'+ {\lfloor {a \over b } \rfloor} y') $
$ \Rightarrow x=-y' \( \) y=-x'-{\lfloor {a \over b } \rfloor}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\n",ans);
	return 0;
}

总结###

没有

posted @ 2017-11-09 10:51  小飞淙的云端  阅读(233)  评论(0编辑  收藏  举报