首页 > 代码库 > K - A/B(逆元)
K - A/B(逆元)
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)。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
Output
对应每组数据输出(A/B)%9973。
Sample Input
2 1000 53 87 123456789
Sample Output
7922 6060
解题思路:
这道题应该用拓展欧几里德算法,总的思路是 (N = 9973):(A/B)%N = ( (A%N) * (1/B)%N)%N
因为 gcd(B,N) = 1,所以 = (n * (gcd(B,N)/B)%N)%
又因为根据拓展欧几里德算法可以得到一组x,y,使得gcd(B,N) = B*x + N*y,代入上式就可以得到
(n * (x + N*y/B)%N)%N= ((n%N) * (x + N*y/B)%N)%N= (n*(x+N*y/B))%N
因为y < B,所以y/B = 0所以原式G= (n*x)%N
又因为x可能为负,所以只要G = (G%N+N)%N,就可以化成正的了。
代码如下:
#include<stdio.h> #include <iostream> using namespace std; int exgcd(int a,int b,int &x,int &y) { int r; int t; if(b==0) { x=1; y=0; return a; } r=exgcd(b,a%b,x,y); t=x; x=y; y=t-a/b*y; return r; } int main() { int T,n,b,x,y; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&b); exgcd(b,9973,x,y); x*=n; x=(x%9973+9973)%9973; printf("%d\n",x%9973); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。