[关闭]
@Chilling 2016-08-11T15:29:12.000000Z 字数 1012 阅读 1097

HDU-1576: 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)。

Output

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

Sample Input

2
1000 53
87 123456789

Sample Output

7922
6060

分析:要求解A/B%9973,已知A%9973,那么我们就需要求出%9973的值。可以使用拓展欧几里得定理或者费马小定理求得B的逆元。


拓展欧几里得

ax+by=gcd(a,b),因此Bx+9973y=GCD(B,9973)=1,求得的x就是B对9973的逆元。再进行计算。

  1. #include<stdio.h>
  2. #define LL long long
  3. #define mod 9973
  4. LL x,y;
  5. void ex_gcd(LL a,LL b)
  6. {
  7. if(b==0)
  8. {
  9. x=1;
  10. y=0;
  11. return;
  12. }
  13. ex_gcd(b,a%b);
  14. int t=x;
  15. x=y;
  16. y=t-a/b*y;
  17. }
  18. int main()
  19. {
  20. int t,n,b;
  21. scanf("%d",&t);
  22. while(t--)
  23. {
  24. scanf("%d%d",&n,&b);
  25. ex_gcd(b,mod);
  26. if(x<0)
  27. x+=mod;
  28. printf("%lld\n",(n*(x%mod))%mod);
  29. }
  30. return 0;
  31. }

费马小定理

由费马小定理可以推得:
B对mod的逆元()等于%mod,这个可以用快速幂取模来求得。

  1. #include<stdio.h>
  2. #define LL long long
  3. #define mod 9973
  4. LL quick(LL x,LL m,LL n)//x^m%n
  5. {
  6. LL ans=1;
  7. while(m>0)
  8. {
  9. if(m%2==1)
  10. ans=ans*x%n;
  11. x=x*x%n;
  12. m=m/2;
  13. }
  14. return ans;
  15. }
  16. int main()
  17. {
  18. LL t,n,b,ans;
  19. scanf("%lld",&t);
  20. while(t--)
  21. {
  22. scanf("%lld%lld",&n,&b);
  23. ans=quick(b,mod-2,mod);
  24. printf("%lld\n",(n*ans)%mod);
  25. }
  26. return 0;
  27. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注