bzoj 3239: Discrete Logging【BSGS】
阿新 • • 發佈:2018-01-26
bzoj bsp i++ urn blog () pac a* scan
BSGS的板子題
此時 \( 0 \leq x \leq p-1 \)
設 \( m=\left \lceil \sqrt{p} \right \rceil ,x=i*m-j \)這裏-的作用是避免逆元
於是可以把式子變形成這樣:\( a^{im}\equiv ba^j(mod p) \)
枚舉右邊\( 0 \leq j <m \) ,用map或者hash以模數為下標來存每一個j
枚舉左邊\( 0 \leq i <m \) ,在map或者hash中查找對應的模數
#include<iostream>
#include<cstdio>
#include<map>
#include<cmath>
using namespace std;
long long a,b,p;
map<long long,long long>mp;
long long ksm(long long a,long long b,long long p)
{
long long r=1ll;
a%=p;
while(b)
{
if(b&1)
r=r*a%p;
a=a*a%p;
b>>=1;
}
return r;
}
int main()
{
while(~scanf("%lld%lld%lld",&p,&a,&b))
{
a%=p;
if(!a&&!b)
{
puts("1");
continue;
}
if(!a)
{
puts("no solution");
continue;
}
if(b==1)
{
puts("0" );
continue;
}
mp.clear();
int m=ceil(sqrt(p)),t=b,f=0;
for(int i=0;i<m;i++)
{
mp[t]=i;
t=(long long)t*a%p;
}
int g=ksm(a,m,p);
t=(long long)g%p;
for(int i=1;i<=m+1;i++)
{
if(mp.count(t))
{
f=1;
printf("%lld\n",i*m-mp[t]);
break;
}
t=(long long)t*g%p;
}
if(!f)
puts("no solution");
}
return 0;
}
bzoj 3239: Discrete Logging【BSGS】