[数论]HDU 1576 A/B 扩展欧几里得算法

传送门:A/B

A/B

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


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
 

Author
xhd
 

Source
HDU 2007-1 Programming Contest
 

解题报告:

此题为扩展欧几里得算法的题。

依题意。

n=A%9973 推出 n=A-A/9973*9973

又∵A/B=x 推出 A=Bx

∴Bx-A/9973*9973=n

转化得 Bx-9973y=n

∵gcd(B,9973)=BX1+9973Y1=1;即可求出X1

等式两边同乘以n

故 B(nX1)-9973(-nY1)=n

可知nX1就是BX-9973Y=n的解

∴x=nx1

为避免负数出现答案应该为(x%9973+9973)%9973


代码如下:

#include
#include
#define MOD 9973
using namespace std;
void ext_gcd(int a,int b,int &x,int &y){  //扩展gcd,可以求出gcd(a,b)以及ax+by=gcd(a,b)中x,y的值
    if(b==0){
        x=1;y=0; return ;
    }
    ext_gcd(b,a%b,x,y);
    int xt=x;
    x=y;
    y=xt-a/b*y;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int x,y;
        int n,b;
        scanf("%d%d",&n,&b);
        ext_gcd(b,MOD,x,y);  //bx+9973y=1
        x*=n;
        int tmp=(x%MOD+MOD)%MOD;
        printf("%d\n",tmp);
    }
    return 0;
}


你可能感兴趣的:(数论,2014寒假)