CF 919E Congruence Equation 费马小+同余(循环节)

本文介绍了一种解决特定形式的模指数方程的方法,利用费马小定理简化计算,并通过枚举结合逆元求解,适用于p为素数的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给出a,b,p,x. p为素数.问有多少个1<=n<=x 满足n*a^n≡b(mod p)
1<=a,b<=p  1<=p<=1e6+3. 1<=x<=1e12.


因为p为素数 由费马小:a^(p-1)≡1 (mod p) a^p=a *a^(p-1) ≡ a (mod p) 得a^n %p 最小循环节为p-1.
n%p的最小循环节显然为p. 那么设n=i*(p-1)+j (0<=j<p) 
n*a^n≡ (i*(p-1)+j)%p * a^(i*(p-1)+j)%(p-1) ≡(j-i)*a^j ≡b (mod p)

因为1<=j<p 现在枚举j 得到 (j-i)≡b*a^-j(modp) 设右边的结果为y,则满足条件的i最小值为j-y.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,p,x;
ll qpow(ll x,ll n,ll mod)
{
	ll s=1;
	while(n)
	{
		if(n&1)
			s=(s*x)%mod;
		x=(x*x)%mod; 
		n>>=1;
	}
	return s;
}
ll inv(ll x)
{
	return qpow(x,p-2,p);	
} 
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>a>>b>>p>>x;
	ll res=0;
	for(ll j=1;j<p;j++)
	{
		ll y=(b*inv(qpow(a,j,p)))%p;
		ll first=((j-y+p)%p)*(p-1)+j;
		if(first>x)	continue;
		res+=(x-first)/((p-1)*p)+1;
	}
	cout<<res<<endl;
	return 0;
}


### SageMath 中处理问题 #### 运算基础概念 在数论中,两个整数 \(a\) 和 \(b\) 对于给定正整数 \(m\) 被称为是模 \(m\) 的,如果它们除以 \(m\) 的差是一个整数倍。表示为: \[ a \equiv b (\text{mod } m) \] 这意味着存在某个整数 \(k\), 使得 \(a-b=km\)。 #### 使用 SageMath 进行基本计算 SageMath 提供了强大的功能来进行各种类型的运算。对于简单的表达式的验证可以直接通过 `%` 符号完成,该符号用于获取两数相除后的数[^1]。 ```python # 定义变量 a, b, m = 7, 2, 5 # 验证是否满足 a ≡ b (mod m) if (a % m) == (b % m): print(f"{a} is congruent to {b} modulo {m}") else: print(f"{a} is not congruent to {b} modulo {m}") ``` #### 执行更复杂的操作 除了简单比较外,还可以执行更加复杂的操作如求解线性方程组、寻找乘法逆元等。下面展示如何找到一个特定数值关于指定模块下的乘法逆元: ```python from sage.all import mod_inverse # 寻找 x 关于模 n 下的乘法逆元 n = 97 x = 38 inverse_x_mod_n = mod_inverse(x, n) print(f"The multiplicative inverse of {x} modulo {n} is {inverse_x_mod_n}.") ``` 上述代码片段展示了如何利用 `mod_inverse()` 函数来查找给定值相对于某一模数的乘法逆元。 #### 解决线性方程式 当面对形如 ax≡c(mod m) 的线性方程时,可以借助中国剩定理或其他方法解决这类问题。这里提供了一个例子说明怎样用 SageMath 来解决问题: ```python def solve_linear_congruence(a, c, m): gcd_val, u0, v0 = extended_gcd(a, m) if c % gcd_val != 0: raise ValueError("No solution exists.") # 计算特解 particular_solution = ((c * u0) // gcd_val) % m return particular_solution def extended_gcd(aa, bb): lastremainder, remainder = abs(aa), abs(bb) x, lastx, y, lasty = 0, 1, 1, 0 while remainder: lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder) x, lastx = lastx - quotient*x, x y, lasty = lasty - quotient*y, y return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1) # 测试函数 result = solve_linear_congruence(3, 4, 7) print(result) ``` 这段 Python 代码定义了两个辅助函数——一个是用来求解广义欧几里德算法(`extended_gcd`)的结果,另一个则是基于前者构建的具体解决方案(`solve_linear_congruence`). 当调用后者并传入适当参数后即可获得相应结果[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值