【洛谷P1082】同余方程【扩欧】

题目大意:

题目链接:https://www.luogu.org/problem/P1082
求关于xx的同余方程ax1(modb)ax \equiv 1 \pmod {b}的最小正整数解。


思路:

数论是真的差,现在才来补qwqqwq
我先把原式改写为等式的形式。
ax1(modb)ax \equiv 1 \pmod {b}
axby=1ax-by=1
然后设xyx'y'为方程bx(amod  b)y=1bx'-(a\mod b)y'=1的一组解。
即为bxy(aab)bx'-y'(a-\lfloor\frac{a}{b}\rfloor)的一组解。
统一格式为
ayb(xyab)ay'-b(x'-\frac{y'a}{b})
那么代入x=y,y=xyabx=y,y=x'-\frac{y'a}{b}即可。
因为gcd(x,0)=xgcd(x,0)=x,当b=0b=0时,必然有a=1a=1。此时该方程的解为x=1,y=0x=1,y=0
然后往上回溯求解即可。
最终我们可以得到该方程的一组解(x,y)(x,y),由于要求xx尽量小且大于0,我们发现为了满足ax+by=1ax+by=1Δax\Delta ax必然等于Δby\Delta by,那么同时要满足x,yx,y均为整数,所以需要找到一组合法的(x,y)(x',y')使得a(x±x)=b(y±y)a(x±x')=b(y±y')
所以Δax\Delta axΔby\Delta by最小等于lcm(a,b)lcm(a,b)。所以Δx\Delta x每次最小为blcm(a,b)\frac{b}{lcm(a,b)}
那么就让xx不停加减blcm(a,b)\frac{b}{lcm(a,b)},知道xx为最小的正整数解为止。其实不断加减就是进行一次取模运算即可。


代码:

#include <cstdio>
#include <algorithm>
#define mp make_pair
#define st first
#define nd second
using namespace std;

int a,b;

pair<int,int> exgcd(int a,int b)
{
	if (b)
	{
		pair<int,int> x=exgcd(b,a%b);
		return mp(x.nd,x.st-x.nd*(a/b));
	}
	return mp(1,0);
}

int main()
{
	scanf("%d%d",&a,&b);
	int x=exgcd(a,b).first,y=b/__gcd(a,b);
	printf("%d",(x%y+y)%y);
	return 0;
} 
posted @ 2019-08-06 07:57  全OI最菜  阅读(107)  评论(0编辑  收藏  举报