HDU 1576 A/B 扩展欧几里德算法

来源:互联网 发布:linux 匹配文件名 编辑:程序博客网 时间:2024/06/10 03:00

A/B

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


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
21000 5387 123456789
 

Sample Output
7922

6060

思路:设(A/B)%9973 = K, 则A/B = k + 9973x  (x未知), 因此A = kB + 9973xB,

又A%9973 = n(n是已知条件),所以kB%9973 = n,  故kB = n + 9973y (y未知)

故(k/n)B +(-y/n)*9973 = gcd(B,9973) = 1(公式中只有k,y不知道)

扩展欧几里得 求出k/n,  再乘以个n,记得取模。

#include<iostream>using namespace std;typedef long long LL;void gcd(LL a,LL b,LL &d,LL &x,LL &y){if(!b) {d=a,y=0,x=1;}else{gcd(b,a%b,d,y,x);y-=x*(a/b);}}int main(){//freopen("E:\\ACM\\test.txt","r",stdin);int T;cin>>T;LL n,B;while(T--){cin>>n>>B;LL a=B;LL b=9973;LL d=1;LL x,y;gcd(a,b,d,x,y);x=(x%b+b)%b;LL k=(x*n)%b;cout<<k<<endl;}return 0;}