• luogu1082 同余方程


    题目大意:求$$axequiv 1( mathrm{mod} m)$$的最小正整数解。

      因为$ax-1|m$,故令$ax-1=-ym$,原方程就变成了$ax+my=1$。根据bezout定理此方程有解当且仅当$gcd(a, m)=1$成立,然后解方程$ax+my=gcd(a,m)$即可。

      先不考虑原题,若要解方程$$ax+by=gcd(a,b)$$,要用到扩展欧几里得算法。当$b=0$时,显然$x=1,y=0$。因为$$gcd(a,b)=gcd(b,a mathrm{mod} b), a mathrm{mod} b=a-lfloor frac{a}{b} floor b$$,所以如果知道了$$bx'+(a-lfloor frac{a}{b} floor b)y'=gcd(b, a mathrm{mod} b)=gcd(a, b)$$,将等式左面倒一倒就变成了$$ay'+b(x'-lfloor frac{a}{b} floor y')=gcd(a,b)$$。所以令当前的$x=y', y=x'-(a/b)*y'$便是一个解。于是在欧几里得算法的基础上加上这一句即可。

    回到原题,人家要求最小正整数解,因为该同余方程$axequiv 1(mod m)$的通解为所有模m与x0同余的整数($ax+amk=a(x+mk)equiv 1( mathrm{mod} m)$依然成立),我们要将解转移使$xin [1,m)$。故将以上解出的$x$进行(x%m+m)%m。x%=m时,$xin (-m,m)$。再加m模m是为了处理x是负数的情况。

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    long long Exgcd(long long a, long long b, long long &x, long long &y)
    {
    	if (b == 0)
    	{
    		x = 1;
    		y = 0;
    		return a;
    	}
    	long long d = Exgcd(b, a%b, x, y);
    	long long tx = x;
    	x = y;
    	y = tx - (a / b)*y;
    	return d;
    }
    
    long long Inv(long long a, long long m)
    {
    	long long x, y;
    	Exgcd(a, m, x, y);
    	return (x%m + m) % m;
    }
    
    int main()
    {
    	long long a, m;
    	scanf("%lld%lld", &a, &m);
    	printf("%lld
    ", Inv(a, m));
    	return 0;
    }
    

      

  • 相关阅读:
    loj#2020. 「AHOI / HNOI2017」礼物
    loj#117. 有源汇有上下界最小流
    loj#6491. zrq 学反演
    loj#6261. 一个人的高三楼
    loj#528. 「LibreOJ β Round #4」求和
    2018-2019 ACM-ICPC Brazil Subregional Programming Contest
    2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest J
    2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)C
    addEventListener() 和 removeEventListener()
    9个图片滑块动画
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8845986.html
Copyright © 2020-2023  润新知