A/B(逆元)

A/B

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


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
 
 
 
就是问你会不会求模的逆元,A/B 的模不能直接除了就取余,要当做 (A* (1/B) )%m 所以就是求 1/B(即B关于MOD的乘法逆元)
费马小定理:  当m为质数的时候  A^(m-1) = 1   (mod m) 即  A^(m-2) = 1/A  (mod m)    两边都余 m
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 
 5 using namespace std;
 6 
 7 #define MOD 9973
 8 
 9 int main()
10 {
11     int T;
12     cin>>T;
13     while(T--)
14     {
15         int a,b;
16         scanf("%d%d",&a,&b);
17         b%=MOD;
18         int c = b;
19         for (int i=0;i<MOD-3;i++)
20             c = (c*b)%MOD;
21         a = (a*c)%MOD;
22         printf("%d\n",a);
23     }
24     return 0;
25 }
View Code

 还可以用扩展欧几里得求逆元,a*x = 1 (mod m) , x 是 a 的逆元,然后,方程等价于 a*x + m*y = 1 (mod m),扩展欧几里得可求得 x0 ,((x0% m)+m)%m 就是最小整数解

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <stdlib.h>
 4 using namespace std;
 5 #define MOD 9973
 6 
 7 int exgcd(int a,int b,int &x,int &y)
 8 {
 9     if (b==0)
10     {
11         x=1;
12         y=0;
13         return a;
14     }
15     int r = exgcd(b,a%b,y,x);
16     y-=(a/b)*x;
17     return r;
18 }
19 
20 int main()
21 {
22     int T;
23     cin>>T;
24     while (T--)
25     {
26         int a,b;
27         cin>>a>>b;
28         int x,y;
29         int r = exgcd(b,MOD,x,y);
30         x=(x%MOD+MOD)%MOD;
31         cout<<a*x%MOD<<endl;
32     }
33     return 0;
34 }
View Code

 

转载于:https://www.cnblogs.com/haoabcd2010/p/6670786.html

<think>嗯,用户想了解如何使用蒙哥马利约简进行A/B计算,可能与密码学或算法实现相关。首先,我需要回顾蒙哥马利约简的基本概念和它在模运算中的应用。蒙哥马利约简主要用于高效计算模乘,特别是在大数运算中,比如RSA或椭圆曲线密码学中常见的操作。 用户提到的是A/B计算,也就是除法,但在模运算中,除法通常转化为乘以模逆元。所以问题可能涉及如何用蒙哥马利约简来实现模逆元的计算,或者将除法转换为乘法。需要明确蒙哥马利域中的运算步骤,比如将数值转换为蒙哥马利形式,进行乘法,再转换回来。 接下来要考虑的是蒙哥马利约简的具体算法步骤。蒙哥马利算法需要一个参数R,使得R大于模数N,并且R与N互质。通常R选择2的幂次,这样可以通过位移来快速计算。约简过程涉及计算临时值,然后通过模R来简化运算,最后得到约简后的结果。 然后是如何将A/B转换为蒙哥马利域中的操作。可能需要先计算B的模逆元,再与A相乘。这时候需要考虑在蒙哥马利域中如何计算模逆元,可能需要扩展欧几里得算法或其他方法。此外,转换A和B到蒙哥马利域需要乘以R并取模,之后在域内进行乘法运算,最后转换回普通域。 还需要注意蒙哥马利算法的实现细节,比如预计算R的平方模N,以及处理负数的可能情况。此外,模逆元的计算可能需要满足B和N互质的条件,这在密码学中通常是成立的,因为N常常是质数或者两个大质数的乘积。 最后,可能需要提供代码示例或伪代码来说明整个过程,帮助用户理解如何具体实现。同时,生成的相关问题应该覆盖蒙哥马利算法的优势、实现中的挑战、在密码学的应用以及与其他模乘方法的比较,这些都能帮助用户更全面地理解主题。</think>### 蒙哥马利约简实现A/B计算的原理与步骤 蒙哥马利约简是一种高效处理模乘运算的算法,特别适用于密码学中大整数的模运算(如RSA、椭圆曲线加密)[^1]。将A/B转换为蒙哥马利域运算的核心步骤如下: #### 1. 数学基础 设模数为$N$,定义常数$R=2^k>N$且$\gcd(R,N)=1$。在蒙哥马利域中,数值$x$表示为: $$x' = x \cdot R \mod N$$ A/B计算等价于: $$A \cdot B^{-1} \mod N$$ #### 2. 算法实现步骤 **步骤1:预计算参数** - 计算$R^2 \mod N$(用于数值转换) - 计算$N'$满足$RR^{-1} - NN' = 1$(通过扩展欧几里得算法) **步骤2:转换到蒙哥马利域** $$ \begin{aligned} A' &= \text{MontRed}(A \cdot R^2 \mod N) \\ B' &= \text{MontRed}(B \cdot R^2 \mod N) \end{aligned} $$ **步骤3:计算模逆元** $$B'^{-1} = \text{MontRed}(B^{N-2} \mod N) \quad (\text{当N为质数时用费马小定理})$$ **步骤4:执行乘法** $$result' = \text{MontMul}(A', B'^{-1})$$ **步骤5:转换回标准域** $$result = \text{MontRed}(result')$$ #### 3. 核心函数伪代码 ```python def mont_red(x, N, N_prime, R_bits): m = (x * N_prime) & (R - 1) # R是2的幂 t = (x + m * N) >> R_bits return t if t < N else t - N def mont_mul(a, b, N, N_prime, R_squared): product = a * b return mont_red(product, N, N_prime, R_bits) ``` #### 4. 密码学应用示例 在RSA解密运算$m = c^d \mod N$中,通过蒙哥马利约简可将模幂运算速度提升30%-50%[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值