【扩展欧几里得】hdu 1576 A/B

来源:互联网 发布:非常嫌疑犯影评知乎 编辑:程序博客网 时间:2024/05/16 07:42

A/B

                            Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                                                    Total Submission(s): 639    Accepted Submission(s): 517


Problem Description
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
 

 

Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
 

 

Output
对应每组数据输出(A/B)%9973。
 

 

Sample Input
2 1000 53 87 123456789
 

 

Sample Output
7922 6060
 

逆元解法:
#include<stdio.h>#define MOD 9973//******************************//返回d=gcd(a,b);和对应于等式ax+by=d中的x,ylong long extend_gcd(long long a,long long b,long long &x,long long &y){    if(a==0&&b==0) return -1;//无最大公约数    if(b==0){x=1;y=0;return a;}    long long d=extend_gcd(b,a%b,y,x);    y-=a/b*x;    return d;}//*********求逆元素*******************//ax = 1(mod n)long long mod_reverse(long long a,long long n){    long long x,y;    long long d=extend_gcd(a,n,x,y);    if(d==1) return (x%n+n)%n;    else return -1;}int main(){    int T;    int n,B;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&B);        int x=mod_reverse(B,MOD);        printf("%d\n",n*x%MOD);    }    return 0;}

扩展欧几里得求ax+by=c解法:
先设(A/B)%9973 = k
--->> A/B = k + 9973 * x
--->> A = kB + 9973*x*B
--->> kB % 9973 = n
--->> 则kB = n + 9973 * y
--->> 则 kB + 9973 *y = n,y属于整数,可正可负
--->>(k / n) * B + 9973*(y / n) = 1
--->> 又gcd(B,9973)= 1
--->> 所以求出k = x *n %9973
#include <iostream>#include <set>#include <map>#include <stack>#include <cmath>#include <queue>#include <cstdio>#include <bitset>#include <string>#include <vector>#include <iomanip>#include <cstring>#include <algorithm>#include <functional>#define PI acos(-1)#define eps 1e-8#define inf 0x3f3f3f3f#define debug(x) cout<<"---"<<x<<"---"<<endltypedef long long ll;using namespace std;///求ax+by=gcd(a,b)的特解x0,y0以及gcd(a,b)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 ans = exgcd(b, a % b, x, y);    long long temp = x;    x = y;    y = temp - (a / b) * y;    return ans;  ///ans=gcd(a,b);}///求ax=c(mod b),即求ax+by=c的最小非负整数解long long cal(long long a, long long b, long long c){    long long x, y;    long long gcd = exgcd(a, b, x, y);    if (c % gcd != 0)    {        return -1;    }    x = x * (c / gcd);    int t = b / gcd;    if (t < 0)    {        t = -t;    }    long long ans = x % t;    if (ans <= 0)    {        ans += t;    }    return ans;}int main(){    long long t, n, b;    cin >> t;    while (t--)    {        cin >> n >> b;        long long ans = cal(b, 9973, 1);        cout << ans*n % 9973 << endl;    }    return 0;}///求ax+by=c的特解:///x0=x0*(c/gcd);///y0=y0*(c/gcd);///求通解:///x=x0+(b/gcd)*k;///y=y0-(a/gcd)*k;/************************************************┆  ┏┓   ┏┓ ┆┆┏┛┻━━━┛┻┓ ┆┆┃       ┃ ┆┆┃   ━   ┃ ┆┆┃ ┳┛ ┗┳ ┃ ┆┆┃       ┃ ┆┆┃   ┻   ┃ ┆┆┗━┓    ┏━┛ ┆┆  ┃    ┃  ┆      ┆  ┃    ┗━━━┓ ┆┆  ┃  AC代马   ┣┓┆┆  ┃           ┏┛┆┆  ┗┓┓┏━┳┓┏┛ ┆┆   ┃┫┫ ┃┫┫ ┆┆   ┗┻┛ ┗┻┛ ┆************************************************ */