数论逆元

Given a positive integer y and a prime p, you are asked to find an integer x such that (x \times y)\ mod\ p= 1(x×y) mod p=1. If such x exists, output any x mod p. Otherwise, output -1.

Hint: For any integer a and positive integer ba mod b is the remainder of a dividing b. Remind that a mod b is non-negative!

The first line of input contains a positive integer T, which is the number of test cases. (1 \le T \le 200,000)(1T200,000)
For each test case, there will be one line containing 2 positive integers y, p. ( 1 \le y, p \le 10^9 )(1y,p109), p is guaranteed to be a prime)

题意:xy≡1(modp).已知y求解x.
思路:首先看一下一元线性同余方程:ax=b (modm) , 即ax除以m, 6除以m, 两者余数相同,这里a、b、m都是整数,求解x的值。

方程也可以这样理解:ax-b是m的整数倍。设y是倍数,那么ax-b=my, 移项得到ax-my=b.因为y可以是负数,改写为ax+my=b, 这就是在扩展欧几里得算法中提到的元一次不定方程。

当且仅当gcd (a,m) 能整除b时有整数解。例如15x+6y=9, 有整数解=1,y=-1.当gcd (a,m) =b时,可以直接用扩展欧几里得算法求解ax+my=b.如果不满足 gcd (a,m) =b, 还能用扩展欧几里得算法求解ax+my=b吗?答案是肯定

的,但是需要结合下面的逆元。

所以这题的b就是1.然后直接套板子就行了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
long long exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    ll ret=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return ret;
}
ll gh(int a,int mod)
{
    ll x,y;
    ll d=exgcd(a,mod,x,y); //利用扩展GCD计算d的值也就是b
    return d==1?(x%mod+mod)%mod:-1;  //如果d是1有解,返回值,否则返回-1
}
int main()
{
    int r;
    scanf("%d",&r);
    while (r--)
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        printf("%lld\n",gh(a,b));
    }

    return 0;
}
View Code

 

posted @ 2020-06-19 17:22  Swelsh-corgi  阅读(153)  评论(0编辑  收藏  举报