zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    CodeForces Gym 100935G Board Game DFS
    CodeForces 493D Vasya and Chess 简单博弈
    CodeForces Gym 100935D Enormous Carpet 快速幂取模
    CodeForces Gym 100935E Pairs
    CodeForces Gym 100935C OCR (水
    CodeForces Gym 100935B Weird Cryptography
    HDU-敌兵布阵
    HDU-Minimum Inversion Number(最小逆序数)
    七月馒头
    非常可乐
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8845986.html
Copyright © 2011-2022 走看看