#Baby Step,Giant Step# [luogu P3846] [TJOI2007] 可爱的质数/【模板】BSGS

Title

https://www.luogu.com.cn/problem/P3846

**大意:**给定整数 a , b , p a,b,p a,b,p,其中 a , p a,p a,p互质,求一个非负整数 x x x,使得 a x ≡ b ( m o d   p ) a^x\equiv b(mod\ p) axb(mod p)


Solution

Baby Step,Giant Step大步小步算法
x = i ∗ t − j x=i*t-j x=itj,其中 t = ∣ p ∣ , 0 ≤ j ≤ t − 1 t=|\sqrt p|,0\le j \le t-1 t=p ,0jt1,则方程变成 a i ∗ t − j ≡ b ( m o d   p ) a^{i*t-j}\equiv b(mod\ p) aitjb(mod p)
对于所有的 j ∈ [ 0 , t − 1 ] j\in [0,t-1] j[0,t1],把 b ∗ a j   m o d   p b*a^j\ mod\ p baj mod p插入一个 H a s h Hash Hash表。
枚举 i i i的所有可能取值,即 i ∈ [ 0 , t ] i\in[0,t] i[0,t],计算出 ( a t ) i   m o d   p (a^t)^i\ mod \ p (at)i mod p,在 H a s h Hash Hash表中查找是否存在对应的 j j j,更新答案即可。时间复杂度为 O ( ( p ) ) O(\sqrt(p)) O(( p))


Code

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#define ll long long 
using namespace std; 
inline ll ksm(ll a,ll b,ll p){
	ll ans=1; 
	for(;b;b>>=1,a=(a*a)%p) if (b&1) ans=(ans*a)%p; 
	return ans; 
}
inline ll baby_step_giant_step(ll a,ll b,ll p){
	map<ll,ll>hash; 
	hash.clear(); 
	b%=p; 
	ll t=(ll)sqrt(p)+1; 
	for(ll j=0;j<t;j++){
		ll val=(long long)b*ksm(a,j,p)%p; 
		hash[val]=j; 
	}
	a=ksm(a,t,p); 
	if (a==0) return b==0?1:-1; 
	for(ll i=0;i<=t;i++){
		ll val=ksm(a,i,p); 
		ll j=hash.find(val)==hash.end()?-1:hash[val]; 
		if (j>=0&&i*t-j>=0) return i*t-j; 
	}
	return -1; 
}
int main(){
	ll a,b,p; 
	scanf("%lld%lld%lld",&p,&a,&b); 
	ll ans=baby_step_giant_step(a,b,p); 
	if (ans!=-1) printf("%lld",ans); else printf("no solution"); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值