费马小定理(应用+拓展)

费马小定理(应用+拓展)

定义:如果两个整数a,p互质,也就是gcd(a,p)=1,那么a^(p-1)≡1( mod p).

公式拓展一下
拓展公式1:n*a^(p-1)≡n(mod p)
拓展公式2:a^(p-2) ≡ a ^(-1) (mod p)
拓展公式3:a^b ≡ a^(bmod(p-1)) (mod p)

求(A/B)%999983,但由于A很大,我们只给出n(n=A%999983)(我们给定的A必能被B整除,且gcd(B,999983) = 1)。
Input

Input

数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 999983)和B(1 <= B <= 10^9)。

Output

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

Sample Input

2
1000 53
87 123456789

Sample Output
660385
801745

解题方法:由于A是一个巨大的数,所以题目中没有告诉你A的大小,而是告诉你了A%999983的值,怎么通过这个值求(A/B)%999983呢?

注意(A/B)%p=(A*B^(-1))%p
所以(A/B)≡(A * B^(-1)) (mod p)
由扩展公式2得到B^(p-2)≡B ^(-1) (mod p)
再由扩展公式1得到 A * B^(p-2)≡A * B ^(-1) (mod p)

所以用快速幂求出B^(p-2)%p,问题就得到解决

代码如下

#include<iostream>
using namespace std;
const int mod=999983;
typedef long long ll;
/*快速幂*/
ll pow_quick(ll dishu,ll zhishu)//dishu是底数,zhishu是指数 
{
	ll answer=1;
	while(zhishu!=0)
	{
		if(zhishu&1)//zhishu%2==1
		{
			answer=answer*dishu%mod;
			zhishu--;
		}
		else
		{
			dishu=dishu*dishu%mod;
			zhishu/=2;
		}
	}
	answer=answer%mod;
	return answer;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		ll n,B;
		scanf("%lld %lld",&n,&B);
		ll ans=n*pow_quick(B,mod-2)%mod;
		printf("%lld\n",ans);
	}
	return 0;
}
### 费马小定理及其在C++中的实现 费马小定理是一个重要的数论工具,在模运算中有广泛应用。它指出如果 \( p \) 是一个素数,而整数 \( a \) 不被 \( p \) 整除,则有: \[ a^{p-1} \equiv 1 \ (\text{mod}\ p) \] 由此可以推导出 \( a^{-1} \equiv a^{p-2} \ (\text{mod}\ p) \),这使得我们可以通过快速幂算法高效地计算乘法逆元。 以下是基于费马小定理的 C++ 示例代码用于计算模意义下的乘法逆元[^1]: ```cpp #include <iostream> using namespace std; // 快速幂函数:计算 (base^exp) % mod 的结果 long long fast_pow(long long base, long long exp, long long mod) { long long result = 1; while (exp > 0) { if (exp & 1) { // 如果指数当前位为1 result = (__int128(result) * base) % mod; // 防止溢出 } base = (__int128(base) * base) % mod; // 平方并取模 exp >>= 1; // 右移一位 } return result; } // 计算 a 关于模 p 的乘法逆元 long long inverse_modulo(long long a, long long p) { return fast_pow(a, p - 2, p); // 使用费马小定理 } int main() { long long a, p; cout << "Enter the value of 'a' and prime number 'p': "; cin >> a >> p; if (a >= p || __gcd((int)a, (int)p) != 1) { cout << "Inverse does not exist or input is invalid." << endl; } else { long long inv = inverse_modulo(a, p); cout << "The modular multiplicative inverse of " << a << " modulo " << p << " is: " << inv << endl; } return 0; } ``` 上述代码实现了两个主要功能: 1. **快速幂**:`fast_pow` 函数利用二分的思想加速幂次计算。 2. **乘法逆元**:调用 `inverse_modulo` 来返回给定数值关于某个素数模的意义下的逆元[^2]。 #### 应用场景分析 费马小定理应用广泛存在于多个领域,特别是在涉及模运算的情况下。例如: - 密码学中 RSA 加密系统的公钥和私钥生成过程需要用到大质数上的模逆元操作。 - 组合计数问题可能需要频繁进行分数形式的结果简化,此时也需要借助模逆元来完成除法模拟[^4]。 另外需要注意的是,当题目规模较大或者精度要求较高时,应考虑数据类型的选取以及防止中间变量越界等问题。以上程序采用了 `__int128` 类型以规避部分潜在风险。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值