题意:
p为素数且a,p互质,求最小的 x 满足上述同余方程
分析:
BSGS算法:
当 p为素数且a,p互质,有费马小定理:,而 ,所以在模p下有长度为P-1的循环节
若原方程有解,则最小的 x 必然在【0,p -1】内
令 ,,,,则:
i,j的范围很小,于是枚举j,将 n*a^j 存入hash表,hash[n*a^j ] = j,
枚举 i ,若a^i*m 的值在hash表中存在,则找到 x 的最小值为 i*m - j;
不难看出,i*m-j 能表示所有在【0,p-1】内的数,如果枚举完 i 都还没有找到,则无解
在用map标记时,j = 0无法标记,通常将 j 枚举到m,i枚举到m+1
代码:
#include <map>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int a,p,c;
ll qpow(ll a,ll x)
{
ll res = 1;
while(x){
if(x&1) res = res * a % p;
a = a * a % p;
x >>= 1;
}
return res%p;
}
int BsGs()
{
map<ll,int> mp;
int k = sqrt(p*1.0) + 0.5;
ll v = c;
for(int j = 1; j <= k ; ++j){
v = v * a % p;
mp[v] = j;
}
v = qpow(a,k);
ll vv = 1;
for(int i = 1; i <= k; ++i){
vv = vv * v % p;
if(mp[vv]) return i * k - mp[vv];
}
return -1;
}
int main()
{
while(cin>>p>>a>>c)
{
int ans = BsGs();
if(ans == -1) cout<<"no solution"<<endl;
else cout<<ans<<endl;
}
return 0;
}